Compare commits

...

1225 commits

Author SHA1 Message Date
mic
5d1d790e39 antispam in progress aligned to the left 2026-05-13 23:00:07 +02:00
Mic
998d626277
Merge pull request #795 from micz/v4.1.0
v4.1.0
2026-05-13 22:52:19 +02:00
Mic
59efb5f007
Merge branch 'main' into v4.1.0 2026-05-13 22:51:22 +02:00
mic
fb52da1436 Merge branch 'v4.1.0' of github.com:micz/ThunderAI into v4.1.0 2026-05-13 22:47:32 +02:00
mic
42d6b11e29 release notes updated 2026-05-13 22:47:26 +02:00
Mic
94019819ec
Merge pull request #794 from micz/tom-select-update-v4.1.0
Update Tom Select files from VENDORS.md
2026-05-13 22:41:38 +02:00
github-actions[bot]
ee853dd447 Update Tom Select files from VENDORS.md 2026-05-13 20:40:43 +00:00
mic
ce3eb57612 tomselect updated. see #793 2026-05-13 22:40:21 +02:00
mic
326bc39ee6 spamfilter_skip_addressbook is now true by default. fixes #785 2026-05-10 23:09:48 +02:00
Mic
538f8b59a9
Merge pull request #782 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-24 21:13:00 +02:00
Mic
c7a9a7812c
Translated using Weblate (French)
Currently translated at 100.0% (592 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-04-24 21:11:51 +02:00
Mic
e1288d65d5
Translated using Weblate (Greek)
Currently translated at 100.0% (592 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-04-24 21:11:50 +02:00
Mic
9bbc5fbc69
Translated using Weblate (German)
Currently translated at 100.0% (592 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-04-24 21:11:50 +02:00
Mic
f7186431d3
Translated using Weblate (Italian)
Currently translated at 100.0% (592 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-04-24 21:11:48 +02:00
Mic
39752e6b35
Translated using Weblate (French)
Currently translated at 96.1% (569 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-04-24 17:08:29 +02:00
Mic
3a0f42f411
Translated using Weblate (French)
Currently translated at 96.1% (569 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-04-23 23:13:31 +02:00
Mic
d6eaa5842b
Translated using Weblate (Italian)
Currently translated at 100.0% (592 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-04-23 23:13:29 +02:00
Mic
13e0ceaefb
Merge pull request #781 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate. Fixes #780
2026-04-23 22:48:56 +02:00
Christos Kanotidis
e7ec1476d7
Translated using Weblate (Greek)
Currently translated at 99.4% (589 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-04-23 20:12:59 +00:00
Mic
5dfcf20714
Merge pull request #777 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-21 19:01:47 +02:00
bittin1ddc447d824349b2
4f620e2cce
Translated using Weblate (Swedish)
Currently translated at 100.0% (592 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-21 17:09:49 +02:00
Mic
71b5c7f7d5
Merge pull request #775 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-20 23:37:30 +02:00
Mic
48f9002f87
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 64.6% (383 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2026-04-20 23:37:03 +02:00
Mic
71848558cd
Translated using Weblate (German)
Currently translated at 78.8% (467 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-04-20 23:37:03 +02:00
Mic
cccdc8442a
Translated using Weblate (Croatian)
Currently translated at 44.5% (264 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2026-04-20 23:37:03 +02:00
Mic
6f0308bbf7
Translated using Weblate (Polish)
Currently translated at 46.1% (273 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2026-04-20 23:37:03 +02:00
Mic
0eaa27f8aa
Translated using Weblate (Russian)
Currently translated at 63.8% (378 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2026-04-20 23:37:03 +02:00
Mic
9f3671e13f
Translated using Weblate (Portuguese (Brazil))
Currently translated at 44.0% (261 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt_BR/
2026-04-20 23:37:03 +02:00
Mic
2f7055db78
Translated using Weblate (Italian)
Currently translated at 81.4% (482 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-04-20 23:37:03 +02:00
Mic
286d127bcd
Translated using Weblate (French)
Currently translated at 78.8% (467 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-04-20 23:37:03 +02:00
Mic
d3086a7711
Translated using Weblate (Japanese)
Currently translated at 69.5% (412 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ja/
2026-04-20 23:37:03 +02:00
Mic
2d924ce74c
Translated using Weblate (Greek)
Currently translated at 75.6% (448 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-04-20 23:37:02 +02:00
Mic
1b8ebb756f
Translated using Weblate (Italian)
Currently translated at 81.4% (482 of 592 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-04-20 23:26:26 +02:00
mic
58e4f5130a prefs_OptionText_hide_thinking_info fixed 2026-04-20 23:26:14 +02:00
mic
8fd5825a8e version set to 4.1.0pre4 2026-04-20 23:10:39 +02:00
mic
2d61e730e5 fix translation json parse. see #247 2026-04-20 23:06:40 +02:00
mic
8cf6f447d4 Merge branch 'v4.1.0' of github.com:micz/ThunderAI into v4.1.0 2026-04-20 22:58:25 +02:00
mic
565134ecbd added thinking hide option. see #636 2026-04-20 22:58:02 +02:00
mic
85afdb0a77 release notes updated 2026-04-20 22:14:52 +02:00
Mic
822953482d
Merge pull request #772 from micz/tom-select-update-v4.1.0
Tom Select 2.6.0
2026-04-20 22:10:24 +02:00
github-actions[bot]
a1888e60f7 Update Tom Select files from VENDORS.md 2026-04-20 20:07:56 +00:00
mic
5977a8feb4 tom-select updated. see #767 2026-04-20 22:07:42 +02:00
mic
9dbfb93e62 added a generic error panel. see #766 2026-04-20 22:06:18 +02:00
Mic
80f8bc1019
Merge pull request #771 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-20 18:40:40 +02:00
bittin1ddc447d824349b2
a5620b7173
Translated using Weblate (Swedish)
Currently translated at 100.0% (586 of 586 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-20 16:39:39 +00:00
Jaroslav Staněk
44daa24840
Translated using Weblate (Czech)
Currently translated at 100.0% (586 of 586 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/cs/
2026-04-20 16:39:38 +00:00
Mic
c7234d035e special prompts validation for config errors. see #766 2026-04-20 18:39:12 +02:00
mic
fc803700fa fixing the timing in btn pressing actions 2026-04-19 23:15:12 +02:00
mic
e28726f30f timing fix when summarizing 2026-04-19 23:08:42 +02:00
mic
83543561d4 summary ai button delay fixed 2026-04-19 23:05:30 +02:00
mic
939c319f6f summary context menu delay fixed 2026-04-19 23:00:51 +02:00
mic
084d289af0 Merge branch 'v4.1.0' of github.com:micz/ThunderAI into v4.1.0 2026-04-19 22:43:51 +02:00
mic
e4f8fcf678 getmailbody calls fixed see #680 2026-04-19 22:43:44 +02:00
Mic
119464bd69
Merge pull request #770 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-19 22:30:47 +02:00
Hosted Weblate
f34431ea6a
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-04-19 22:22:43 +02:00
Mic
7b99c1c5b3
Merge pull request #769 from micz/new_menu_issue680
New menu issue 680
2026-04-19 22:22:37 +02:00
Mic
cccd3346a5
Merge branch 'v4.1.0' into new_menu_issue680 2026-04-19 22:22:25 +02:00
mic
8b1e130bb4 default menu items show_in fixed to have the same old behaviour. see #680 2026-04-19 22:17:48 +02:00
mic
1baac228c0 addtags popup menu fixed 2026-04-18 23:06:34 +02:00
Mic
a10bd5725b
Merge pull request #768 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-18 22:53:57 +02:00
Gerardo Sobarzo
e717b827b4
Translated using Weblate (Spanish)
Currently translated at 100.0% (572 of 572 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-04-18 22:13:08 +02:00
mic
9fac73c319 working on special prompt on popup menu. see #680 2026-04-17 22:57:19 +02:00
mic
0a99b28067 typo fix 2026-04-17 22:29:08 +02:00
mic
d383e78503 old prompt_summarize_this prompt removed 2026-04-17 22:26:29 +02:00
mic
8ba30a1b7c release notes updated 2026-04-17 22:16:14 +02:00
mic
d007ed37e9 version set to 4.0.7. release notes updated 2026-04-17 22:11:07 +02:00
Mic
82d38f7ebe
Merge pull request #759 from micz/improved_body_decoding
Improved multipart HTML body decoding
2026-04-17 22:09:11 +02:00
Mic
fa885f44dd improved multipart html body decoding 2026-04-17 21:40:47 +02:00
Mic
0691a027a9
Merge pull request #765 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-17 21:37:50 +02:00
Gerardo Sobarzo
48128b978d
Translated using Weblate (Spanish)
Currently translated at 82.1% (470 of 572 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-04-17 19:24:31 +00:00
Mic
ec5506ed8a typo fixed 2026-04-17 02:01:00 +02:00
Mic
4704a884a1 typo fixed 2026-04-17 02:01:00 +02:00
Mic
35bc236ce5 added a border to editable icons. see #680 #184 2026-04-17 01:59:00 +02:00
Mic
4c7b38fffc added other context menu icons. see #680 #184 2026-04-17 01:53:00 +02:00
Mic
954c650d4b empty_icon fixed for dark mode. see #680 #184 2026-04-17 01:44:00 +02:00
Mic
f903149e51 more context menu icons added. see #680 #184 2026-04-17 01:38:00 +02:00
Mic
3240177717 prompt import / export fixed. see #680 2026-04-17 01:35:00 +02:00
Mic
2a51e39815 context menu icons folder rearranged. see #680 #184 2026-04-17 01:29:00 +02:00
Mic
cfc0aedb98 context menu icons added. see #680 #184 2026-04-17 01:21:00 +02:00
Mic
e6bc740adf README updated 2026-04-17 01:12:00 +02:00
Mic
0ee53d6b37 context menu images added. see #680 #184 2026-04-17 01:12:00 +02:00
Mic
43fcc972b5 code impagination 2026-04-17 01:12:00 +02:00
Mic
4d145db282
Fix formatting for Swedish translation entry 2026-04-17 00:09:25 +02:00
Mic
1ac16ed4c2 [] removed from the specific api integration label in the options page 2026-04-16 23:20:30 +02:00
Mic
62629fe191
Merge pull request #762 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-16 23:17:31 +02:00
Mic
1eb1ef6dc1 defaultContextMenuIcon set to empty. see #680 2026-04-16 23:16:32 +02:00
Mic
e4c065df7b spec files updated. see #680 2026-04-16 23:00:07 +02:00
Mic
4575ab795d release notes updated 2026-04-16 22:59:21 +02:00
Mic
3a506f710f menu order reloading fixed. see #680 2026-04-16 22:54:52 +02:00
Mic
dd1aba576d reloading menu order page on prompts save. see #680 2026-04-16 22:52:29 +02:00
Mic
13a5e273ef menu order button replaced. see #680 2026-04-16 22:44:58 +02:00
Mic
e2b20e7ed6 prompt_get_calendar_event_from_clipboard fixed. see #680 2026-04-16 22:37:51 +02:00
Mic
3eba2865d7 typo fixed 2026-04-16 22:29:16 +02:00
Mic
23e8fb9e07 save all position fixed. see #680 2026-04-16 22:28:10 +02:00
Mic
a5e3ac9a07 disabled prompts are not visible. see #680 2026-04-16 22:26:31 +02:00
Mic
1984a70b28 dynamic_menu_order_alphabet option removed. see #680 2026-04-16 22:20:37 +02:00
Mic
a98e2edafe migrateMenuOrderAlphabetic implemented. see #680 2026-04-16 22:18:24 +02:00
Mic
8522a28a7d no more menu items alphabetical order. see #680 2026-04-16 22:11:40 +02:00
Mic
a402f378f0 title css fixed. see #680 2026-04-16 22:09:13 +02:00
Mic
156a0fa9a8 save button improved. see #680 2026-04-16 21:41:56 +02:00
Andreas Pettersson
c0a95f41fa
Translated using Weblate (Swedish)
Currently translated at 100.0% (572 of 572 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-16 04:09:50 +00:00
Mic
fa54572279 tab filtering fixed. see #680 2026-04-15 23:39:00 +02:00
Mic
e89ab5beca inactive features items hidded. see #680 2026-04-15 23:31:00 +02:00
Mic
14868d4fd4 order menu feature first try. see #680 2026-04-15 23:25:00 +02:00
mic
591120a571 release notes updated 2026-04-14 23:25:56 +02:00
mic
0e58db3f9e description improved 2026-04-14 23:23:42 +02:00
mic
9c72d2fc05 wrong coninue removed 2026-04-14 23:22:07 +02:00
mic
e4f3ff9351 added isAutoMode. see #749 2026-04-14 23:21:12 +02:00
mic
0eb8b41f33 css fixes 2026-04-14 23:02:42 +02:00
mic
9f525231f9 fix buttons position 2026-04-14 22:56:12 +02:00
mic
584bc32ec5 dynamic elements in antispam badge 2026-04-14 22:50:15 +02:00
mic
487d4e33af improving the antispam graphic 2026-04-14 22:46:18 +02:00
Mic
8522f0b7f6 improved multipart html body decoding 2026-04-12 22:10:00 +02:00
Mic
67f30ee6bc
Merge pull request #756 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-12 08:33:48 +02:00
Andreas Pettersson
6f665b1892
Translated using Weblate (Swedish)
Currently translated at 100.0% (572 of 572 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-12 00:09:49 +02:00
mic
79d15ee0cf release notes updated 2026-04-10 23:51:56 +02:00
mic
68084a6718 api webchat messages have now different colors. See #3 2026-04-10 23:50:49 +02:00
mic
b235005911 release notes fixed 2026-04-10 23:36:21 +02:00
mic
d96d7ab025 release notes updated 2026-04-10 23:34:26 +02:00
mic
7c984dc74d mail_full_headers placeholder added. see #713 2026-04-10 23:33:15 +02:00
mic
9c50345127 version set to 4.1.0pre3 2026-04-10 23:15:12 +02:00
mic
fc1091bd0c moved positioning of the translate branding. see #744 2026-04-10 23:10:01 +02:00
mic
7e9ef4c378 moved positioning of the summary branding. see #744 2026-04-10 23:03:53 +02:00
Mic
7f2de50726
Merge pull request #754 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-10 22:11:50 +02:00
bittin1ddc447d824349b2
db2d31a7bc
Translated using Weblate (Swedish)
Currently translated at 99.8% (569 of 570 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-10 20:10:10 +00:00
Mic
200e035f6b release notes updated 2026-04-10 01:09:00 +02:00
Mic
c625f2f351 allowing different date time formats. see #737 2026-04-10 01:01:00 +02:00
Mic
e29974af14
Merge pull request #752 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-10 00:25:54 +02:00
Hosted Weblate
01e5226524
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-04-09 22:24:21 +00:00
mic
7ae4aa1899 antispam filter added the addressbook skip option. see #748 2026-04-10 00:24:13 +02:00
mic
e6d6a095ac ChatGPT web models accelerators removed. see #692 2026-04-09 23:41:07 +02:00
Mic
a988a16bec
Merge pull request #751 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-09 22:21:17 +02:00
Mic
cba4eb2490
Translated using Weblate (Portuguese (Brazil))
Currently translated at 47.3% (268 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt_BR/
2026-04-09 22:20:53 +02:00
Mic
678b1c0723
Translated using Weblate (Italian)
Currently translated at 84.6% (479 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-04-09 22:20:53 +02:00
Mic
a3b8ccd588
Translated using Weblate (Russian)
Currently translated at 68.5% (388 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2026-04-09 22:20:52 +02:00
Mic
50dbc6a6d9
Translated using Weblate (Swedish)
Currently translated at 99.8% (565 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-09 22:20:52 +02:00
Mic
551e697478
Translated using Weblate (French)
Currently translated at 84.6% (479 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-04-09 22:20:51 +02:00
Mic
33c60ec189
Translated using Weblate (Spanish)
Currently translated at 74.7% (423 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-04-09 22:20:50 +02:00
Mic
7c7e83457f
Translated using Weblate (Croatian)
Currently translated at 47.8% (271 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2026-04-09 22:20:50 +02:00
Mic
31283f7f7e
Translated using Weblate (Czech)
Currently translated at 63.4% (359 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/cs/
2026-04-09 22:20:50 +02:00
Mic
e48f3a339d
Translated using Weblate (Japanese)
Currently translated at 74.5% (422 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ja/
2026-04-09 22:20:50 +02:00
Mic
cfda255495
Translated using Weblate (Polish)
Currently translated at 49.8% (282 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2026-04-09 22:20:50 +02:00
Mic
01fda7a43a
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 69.4% (393 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2026-04-09 22:20:50 +02:00
Mic
5310be1059
Translated using Weblate (German)
Currently translated at 84.6% (479 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-04-09 22:20:50 +02:00
Mic
024260009d
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 65.5% (371 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-04-09 22:20:50 +02:00
Mic
fd8afc5d1b
Translated using Weblate (Greek)
Currently translated at 81.2% (460 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-04-09 22:20:50 +02:00
mic
df0e26ebee release notes updated 2026-04-09 22:10:08 +02:00
mic
b0b85b3353 get calendar event prompt updated for a full day event. see #750 2026-04-09 22:09:12 +02:00
Mic
fbedb7dfd9
Add ThunderAI Prompt Architect link to README
Added a section for ThunderAI Prompt Architect with attribution.
2026-04-09 21:28:29 +02:00
Mic
c9625ef8c6
Merge pull request #747 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-08 18:34:45 +02:00
67
7a5de636b5
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 65.5% (371 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-04-08 15:09:51 +02:00
bittin1ddc447d824349b2
5ea940ee74
Translated using Weblate (Swedish)
Currently translated at 99.8% (565 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-08 15:09:48 +02:00
Mic
14bf5cfd10
Merge pull request #745 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-07 23:22:48 +02:00
Mic
2f0d4331d6
Translated using Weblate (French)
Currently translated at 84.6% (479 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-04-07 23:22:17 +02:00
Mic
f31edbc569
Translated using Weblate (Czech)
Currently translated at 63.4% (359 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/cs/
2026-04-07 23:22:17 +02:00
Mic
13c8aeb86e
Translated using Weblate (Portuguese (Brazil))
Currently translated at 47.3% (268 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt_BR/
2026-04-07 23:22:16 +02:00
Mic
79e63a6bd5
Translated using Weblate (Russian)
Currently translated at 68.5% (388 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2026-04-07 23:22:16 +02:00
Mic
869054c6f7
Translated using Weblate (Swedish)
Currently translated at 99.2% (562 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-07 23:22:16 +02:00
Mic
6cbd97f717
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 69.4% (393 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2026-04-07 23:22:16 +02:00
Mic
09aa9b4942
Translated using Weblate (German)
Currently translated at 84.6% (479 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-04-07 23:22:16 +02:00
Mic
8740438c2d
Translated using Weblate (Polish)
Currently translated at 49.8% (282 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2026-04-07 23:22:16 +02:00
Mic
d91e5b5499
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 53.1% (301 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-04-07 23:22:16 +02:00
Mic
f0ca5807a2
Translated using Weblate (Greek)
Currently translated at 81.2% (460 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-04-07 23:22:16 +02:00
Mic
7855250d84
Translated using Weblate (Croatian)
Currently translated at 47.8% (271 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2026-04-07 23:22:16 +02:00
Mic
796a599cc6
Translated using Weblate (Japanese)
Currently translated at 74.5% (422 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ja/
2026-04-07 23:22:16 +02:00
Mic
bfe206295f
Translated using Weblate (Spanish)
Currently translated at 74.7% (423 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-04-07 23:22:15 +02:00
Mic
79f34b6ed8
Translated using Weblate (Italian)
Currently translated at 84.6% (479 of 566 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-04-07 23:22:15 +02:00
mic
c3d0610d94 spam filter prompt updated 2026-04-07 23:18:02 +02:00
mic
41697280ca release notes updated 2026-04-07 23:05:32 +02:00
mic
474e58097c added the antispam skip list. see #743 2026-04-07 23:02:05 +02:00
mic
0dc9ecce38 HTML title removed because Thunderbird is setting its title and then changing it after the windows creation and we are already doing that see https://github.com/micz/ThunderAI/issues/696#issuecomment-4190953876 2026-04-06 23:08:10 +02:00
mic
a92d2f4c55 HTML title removed because Thunderbird is setting its title and then changing it after the windows creation and we are already doing that see https://github.com/micz/ThunderAI/issues/696#issuecomment-4190953876 2026-04-06 23:06:59 +02:00
Mic
78c629a1bc
Merge pull request #741 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-06 22:38:24 +02:00
Andreas Pettersson
c6eb5aaa0e
Translated using Weblate (Swedish)
Currently translated at 100.0% (562 of 562 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-06 21:09:48 +02:00
bittin1ddc447d824349b2
80d9765080
Translated using Weblate (Swedish)
Currently translated at 100.0% (562 of 562 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-06 11:09:49 +00:00
Mingxin
ff7d097fda
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 53.5% (301 of 562 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-04-06 11:09:48 +00:00
mic
b17d094d0c the trigger "edited" removed from the workflow. 2026-04-06 00:15:32 +02:00
mic
ffcb1e1b9c positioning fixed 2026-04-06 00:04:13 +02:00
mic
eac4f0565f version set to 4.1.0pre2 2026-04-05 23:56:24 +02:00
mic
6a87381b3c added an option to always use a plain text summary. see #740 2026-04-05 23:54:56 +02:00
mic
bddd630bb9 "Please" removed 2026-04-05 23:43:26 +02:00
mic
9366ac226d summarize prompt improved for a concise summary with no formatting. see #580 2026-04-05 23:42:58 +02:00
Mic
3c9c8a55d1
Merge pull request #738 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-03 23:29:02 +02:00
bittin1ddc447d824349b2
3b4426f530
Translated using Weblate (Swedish)
Currently translated at 100.0% (560 of 560 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-03 15:09:49 +00:00
mic
4ab2af98a3 working on new menus. see #680 2026-04-02 22:12:57 +02:00
Mic
1494651de6 show_in = none removed. see #680 2026-04-02 21:45:46 +02:00
Mic
85047f80c6
Merge pull request #735 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-02 21:38:47 +02:00
Hosted Weblate
9ac56c1fd6
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-04-02 19:36:57 +00:00
Andreas Pettersson
613cbc2179
Translated using Weblate (Swedish)
Currently translated at 100.0% (556 of 556 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-04-02 19:36:55 +00:00
Mic
010b9ad9df release notes updated 2026-04-02 21:36:23 +02:00
Mic
774c63ef9e new menus first try. see #680 2026-04-02 00:23:00 +02:00
Mic
f64d49ccf1 few i18n strings added 2026-04-02 00:14:00 +02:00
Mic
983d1e3fcf In the options page is shown if a special prompt is using a specific API. see #676 2026-04-02 00:14:00 +02:00
Mic
ce041fad64 format: json added to Ollama. see #703 2026-04-02 00:09:00 +02:00
Mic
ca56c2d971 now the popup closes immediatly. see #677 2026-04-02 00:09:00 +02:00
Mic
28e61d7a40 correctly showing connection info. see #730 2026-04-02 00:04:00 +02:00
Mic
742034ce82
Add documentation section to README
Added documentation section with setup guides and custom prompt tutorial links.
2026-04-01 23:40:48 +02:00
Mic
c1396ebfb4
Merge pull request #734 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-04-01 23:34:32 +02:00
Hosted Weblate
89de33ebde
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-04-01 23:30:09 +02:00
Mic
01ef569d4d
Merge pull request #733 from micz/translations_issue247
Automatic Translations
2026-04-01 23:29:59 +02:00
Mic
34eaabda74
Merge branch 'v4.1.0' into translations_issue247 2026-04-01 23:29:49 +02:00
mic
6f74c32c2e version set to 4.1.0pre1 2026-04-01 23:24:28 +02:00
mic
78dfaae3f1 release notes updated 2026-04-01 23:24:16 +02:00
mic
e33095ca23 translated subject visualization improved. see #247 2026-04-01 23:19:58 +02:00
mic
c50406bae0 normalizing also accented characters when creating new tags. see #732 2026-04-01 23:10:30 +02:00
mic
f1f8d4d3eb typo fixed 2026-04-01 23:10:18 +02:00
mic
a87420c155 release notes updated 2026-04-01 23:05:37 +02:00
mic
da82fb0b6d normalizing also accented characters when creating new tags. see #732 2026-04-01 23:03:34 +02:00
mic
9df3667e75 version set to 4.0.6 2026-04-01 23:00:27 +02:00
mic
83f856d1ae trasnlate webchat removed. see #247 2026-04-01 00:34:26 +02:00
mic
c0ebc646b8 some fixes on JSON translation. see #247 2026-04-01 00:27:47 +02:00
mic
38f6b1987d the translation prompt now returns a JSON. see #247 2026-04-01 00:19:35 +02:00
mic
894d3475dd iconse renamed and translate for context menu added 2026-03-30 23:07:53 +02:00
mic
c5c7694d51 tranlsate context menu added. see #247 #719 2026-03-30 23:02:22 +02:00
mic
7e5ba820c2 thunderai_translate_lang and thunderai_translate_exclude_lang placeholders added. see #247 #726 #727 2026-03-30 21:49:16 +02:00
mic
41071e3256 translation id fixed 2026-03-30 21:45:42 +02:00
Mic
473d41d110
Merge pull request #731 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-30 21:11:31 +02:00
Andreas Pettersson
5eab777885
Translated using Weblate (Swedish)
Currently translated at 100.0% (520 of 520 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-03-29 23:09:48 +00:00
mic
0b5d410afd translate_exclude_lang option added (but not used at the moment). see #247 #720 2026-03-29 23:00:01 +02:00
mic
f1b42f8714 warning on empty lang. see #247 #716 2026-03-29 22:52:47 +02:00
mic
4ce2a0fc6e storage info improved. see #580 2026-03-29 22:41:05 +02:00
mic
45da8622aa in-message UI improved 2026-03-29 22:37:28 +02:00
mic
1018fa777d improved the UI of the in messages panels 2026-03-29 22:25:25 +02:00
mic
0945ea7d6e spec file updated 2026-03-28 18:51:42 +01:00
mic
a1632f628e sv locale updated 2026-03-28 12:50:06 +01:00
mic
1650322f4d cache renamed to storage 2026-03-28 12:48:14 +01:00
mic
374d598d70 cache renamed to storage 2026-03-28 12:47:58 +01:00
mic
226599ed2a cache renamed to storage 2026-03-28 12:46:42 +01:00
mic
7580efb661 cache renamed to storage 2026-03-28 12:46:04 +01:00
mic
03c241c974 css fix 2026-03-28 12:41:59 +01:00
mic
69654fcb31 graphic attribution updated 2026-03-28 12:18:15 +01:00
mic
13d82d8dbf "translation by" added. translation icon added. 2026-03-28 12:16:36 +01:00
mic
fa6b5c95a9 panels on message ordered 2026-03-28 12:10:00 +01:00
mic
1b0da7ce61 string added to i18n 2026-03-28 12:02:34 +01:00
mic
f10beb8097 onreceive translate added. see #247 #721 2026-03-28 11:55:06 +01:00
mic
2d478edfb9 fields handling improved 2026-03-28 11:47:21 +01:00
mic
6c6b57e6ea i18n updated 2026-03-28 11:45:50 +01:00
mic
a931c864d2 summarize now is possibile on also mail receive. see #580 #723 2026-03-28 11:44:09 +01:00
mic
a8c69d4426 summarize now is possibile on aslo mail receive. see #580 #723 2026-03-28 11:39:11 +01:00
Mic
61916c1a85
Merge pull request #724 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-28 11:10:59 +01:00
mic
b4e41c0ba0 summarize batch option added 2026-03-28 11:07:40 +01:00
bittin1ddc447d824349b2
92b8853861
Translated using Weblate (Swedish)
Currently translated at 100.0% (519 of 519 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-03-28 11:04:12 +01:00
mic
13681c297b summarize batch option added 2026-03-28 11:03:56 +01:00
mic
ef7483031d translate_display_mode and translate_max_display_length added. see #247 2026-03-28 00:21:45 +01:00
mic
32abc00693 mail translation first try. see #247 2026-03-27 23:59:17 +01:00
mic
681f0f0f18 clear cache button added in the options page. see #675 2026-03-27 23:25:09 +01:00
mic
a908efc88d release notes updated 2026-03-27 23:20:58 +01:00
Mic
2066a82622
Merge pull request #715 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-27 23:13:23 +01:00
Hosted Weblate
99b07fb5d2
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-03-27 23:08:52 +01:00
Mic
12eb740219
Merge pull request #714 from micz/summary_on_message_issue580
Summary on message issue 580
2026-03-27 23:08:40 +01:00
mic
2460e40bf7 fix removing html elements added by thunderai when extracting text or html from the email. see #710 2026-03-27 23:06:53 +01:00
mic
9f929ff003 release notes updated 2026-03-27 23:01:09 +01:00
mic
0b3c66b78d fix removing html elements added by thunderai when extracting text or html from the email. see #710 2026-03-27 23:00:33 +01:00
Mic
29ed9e6df6 Merge branch 'summary_on_message_issue580' of github.com:micz/ThunderAI into summary_on_message_issue580 2026-03-27 22:13:07 +01:00
Mic
61eb858f5a stripping printing headers from the html body berfore using it in a placeholder 2026-03-27 00:35:00 +01:00
mic
942c5a6143 removing html elements added by thunderai when extracting text or html from the email. see #710 2026-03-27 00:30:00 +01:00
mic
5301d1c898 escaping html code also in chatgpt web integration. see #711 2026-03-27 00:30:00 +01:00
mic
1d8543627e html mail parts are now displayed as code and are not rendered. see #711 2026-03-27 00:30:00 +01:00
Mic
7d2b811926 stripping printing headers from the html body berfore using it in a placeholder 2026-03-27 00:24:00 +01:00
Mic
43ffdd32e1 release notes updated 2026-03-27 00:24:00 +01:00
mic
b1b02312e9 release notes updated 2026-03-27 00:24:20 +01:00
mic
696ef5aa3c removing html elements added by thunderai when extracting text or html from the email. see #710 2026-03-27 00:22:43 +01:00
mic
0e9790ccf4 release notes updated 2026-03-26 23:46:40 +01:00
mic
3623b92ea5 The API webchat window now has a dynamic title. see #696 2026-03-26 23:44:20 +01:00
mic
63f52703b7 escaping html code also in chatgpt web integration. see #711 2026-03-26 23:41:13 +01:00
mic
36d606bbc6 html mail parts are now displayed as code and are not rendered. see #711 2026-03-26 23:36:49 +01:00
mic
40235e5df4 version set to 4.0.5 2026-03-26 23:29:28 +01:00
mic
afdae833dc release notes updated 2026-03-26 00:14:35 +01:00
mic
0d51829c8e improved _initSummary to chedk the summarize pref. changed summarize_auto, now defaults to 1. see #580 2026-03-26 00:09:06 +01:00
mic
fadae81328 css fix 2026-03-26 00:00:48 +01:00
mic
7e9b507f0f keeping formatted summary #580 2026-03-25 23:59:20 +01:00
mic
3cb1fb0972 correctly using the ai webchat if the relative option is configured accordingly. see #580 2026-03-25 23:43:48 +01:00
mic
8a0e6e5cae release notes updated 2026-03-25 23:23:03 +01:00
Mic
1522e2c04c version set to 4.0.4. release notes updated 2026-03-25 00:19:00 +01:00
Mic
a1bd5d71e6 correctly setting the current model in the special prompts pages 2026-03-25 00:13:00 +01:00
Mic
021e317a37 correctly setting the current model in the special prompts pages 2026-03-25 00:13:00 +01:00
Mic
7cde1f9b62 added a transition. see #705 2026-03-25 00:05:00 +01:00
Mic
33fecf3afe summary: see more / see less added. see #580 2026-03-25 00:01:00 +01:00
mic
e29079ddc9 correctly loading the working icon. see #707 2026-03-25 00:06:37 +01:00
mic
d7a362f5df summarize btn position fixed when adding spamreport div 2026-03-24 23:58:26 +01:00
mic
8ba35a34ba summary btn position fixed 2026-03-24 23:55:44 +01:00
mic
d2486f7f5e summary generating messaage color fixed. see #580 2026-03-24 23:52:57 +01:00
mic
b2eb872557 positioning fixed. see #580 2026-03-24 23:48:13 +01:00
mic
d66c897ad1 readme updated 2026-03-24 23:38:43 +01:00
mic
c0a5be76b7 ai summary icon added. see #580 2026-03-24 23:37:18 +01:00
mic
6bfeeca90d summary butoon with an ai sumamry icon added. see #580 2026-03-24 23:36:25 +01:00
mic
ea0d1e5e86 summary title removed. see #580 2026-03-24 23:25:47 +01:00
mic
0ea8c02202 summary branding added. see #580 2026-03-24 23:22:53 +01:00
mic
8494113886 css fixes 2026-03-24 23:20:51 +01:00
mic
db41bce928 spamreport olways on top. see #706 2026-03-24 23:11:22 +01:00
mic
6b37ba894b icons are now in a menu 2026-03-24 22:15:32 +01:00
mic
630938e30f hover color added 2026-03-24 18:50:19 +01:00
mic
438670d28c css fix 2026-03-24 18:46:54 +01:00
Mic
e02a8b1c14 loading indicator for summary added. see #580 2026-03-24 00:31:00 +01:00
Mic
9a00477067 hover colors improved 2026-03-24 00:27:00 +01:00
Mic
fe0804a9dd collapse icon added to summary report. see #580 2026-03-24 00:19:00 +01:00
Mic
8d166b314e delete and refresh buttons are now styled the same 2026-03-24 00:14:00 +01:00
Mic
9e0fb5bf73 improved spamreport code 2026-03-24 00:12:00 +01:00
Mic
b08b8563d0 code refactored to have one method to calculate the final prompt. see #580 2026-03-24 00:01:00 +01:00
Mic
a505f22261 minor fixes 2026-03-23 23:59:00 +01:00
mic
6e30ea9159 always showing a summary if present. see #580 2026-03-23 23:32:04 +01:00
mic
58437ad168 summarize_display_mode added. see #580 2026-03-23 23:31:48 +01:00
mic
7bac86cc82 spec updated 2026-03-23 22:21:03 +01:00
Mic
83b8544404 taSummaryStore is now a Class and is using taStorage. see #675 #580 2026-03-23 18:39:21 +01:00
Mic
6d53e108d0 taSummaryCache renamed to taSummaryStore 2026-03-23 18:25:35 +01:00
Mic
d2604518ea
Merge pull request #579 from yonie/main
feat(summary): add AI-powered message summary feature
2026-03-23 18:16:57 +01:00
Mic
65bf9c440c
Merge branch 'summary_on_message_issue580' into main 2026-03-23 18:14:08 +01:00
Mic
1ccd3d3123 taStorage constants added 2026-03-23 00:22:00 +01:00
mic
170dddfb78 log statements added 2026-03-22 22:49:42 +01:00
mic
eba28e0919 antispam panel css fix 2026-03-22 22:44:12 +01:00
mic
1ea548a61d taSpamReport is now a class and not a singleton 2026-03-22 22:38:23 +01:00
mic
55240868dd spamreport is using the new storage. see #675 2026-03-22 22:29:31 +01:00
mic
b30da27c84 method comments updated 2026-03-22 15:32:10 +01:00
mic
038e6f6fed hasfield gets now a record object. see #675 2026-03-22 15:30:40 +01:00
mic
08f9568955 var name fixed 2026-03-22 15:28:00 +01:00
mic
e95808d1fe Storage class first try. see #675 2026-03-20 23:50:25 +01:00
mic
bb43f37815 removed unused import 2026-03-20 21:30:35 +01:00
mic
64bb41633e CLAUDE.md updated 2026-03-20 21:27:14 +01:00
mic
bc3acef47b copyright statement year updated 2026-03-20 21:24:57 +01:00
mic
216bdb3022 version set to 4.1.0 2026-03-20 21:05:03 +01:00
mic
cf5ba3450a The API webchat window now has a dynamic title. see #696 2026-03-20 18:32:11 +01:00
mic
b7f3b15b2a version set to 4.0.3, release notes updated 2026-03-20 17:51:58 +01:00
mic
c2653ce3aa Fixed a bug in the sanitizeString method. see #698 2026-03-20 17:50:30 +01:00
mic
61c8282a0d gitignore added 2026-03-15 23:45:38 +01:00
mic
f5118e250b CLAUDE.md file improved and added specifications files in claude-spec 2026-03-15 22:00:28 +01:00
Mic
cb1e0d0d47
Update feature request link in bug report template 2026-03-14 12:47:25 +01:00
Mic
adc65fd07a
Merge pull request #695 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-11 22:17:34 +01:00
Christos Kanotidis
65b4346ec3
Translated using Weblate (Greek)
Currently translated at 96.0% (465 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-03-11 22:17:24 +01:00
mic
14e3d9b0c7 prepared for release 2026-03-11 22:16:14 +01:00
Mic
c29b4d473b
Add additional contributors for Chinese translations 2026-03-07 16:52:32 +01:00
Mic
5d30181af7
Merge pull request #694 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-07 16:51:42 +01:00
Mingxin
bbea54b822
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 61.5% (298 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-03-07 13:09:52 +01:00
Mic
cf5997ace6
Merge pull request #693 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-07 01:03:18 +01:00
Andreas Pettersson
11e8d5b8c2
Translated using Weblate (Swedish)
Currently translated at 100.0% (484 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-03-07 00:09:54 +01:00
mic
3352eac090 Merge branch 'main' of github.com:micz/ThunderAI 2026-03-06 23:42:34 +01:00
mic
9181b11ca1 guides and tutorial links localized 2026-03-06 23:42:10 +01:00
mic
4f738b7ce6 guides and tutorial links localized 2026-03-06 23:41:49 +01:00
mic
931e95d314 isWithinBounds check removed. see #685 2026-03-06 23:04:26 +01:00
mic
6ca4687b3e version set to 4.0.2pre1 2026-03-06 22:54:51 +01:00
mic
2534c499d0 sanitizeString fixed. see #689 2026-03-06 22:54:11 +01:00
Mic
0a3e697011 release notes updated 2026-03-06 18:37:03 +01:00
Mic
910f55dc19 correctly fixing tags IDs. see #689 2026-03-06 00:02:00 +01:00
Mic
e788f305a0 openai api response.failed correctly handled. see #690 2026-03-06 00:00:00 +01:00
Mic
50d8e8e41f added a log of the full raw AI response after streaming 2026-03-05 23:52:00 +01:00
Mic
c275625111 fixing white lines. see #686 2026-03-05 23:43:00 +01:00
Mic
2e5581414b
Merge pull request #682 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-03-04 22:55:12 +01:00
Mic
bc08959593
Translated using Weblate (German)
Currently translated at 100.0% (484 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-03-04 22:54:22 +01:00
Mic
e089669eec
Translated using Weblate (French)
Currently translated at 100.0% (484 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-03-04 22:54:22 +01:00
Mic
018684cf02
Translated using Weblate (German)
Currently translated at 98.1% (475 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-03-04 21:47:01 +00:00
Mic
b505dc7747
Translated using Weblate (Portuguese)
Currently translated at 11.9% (58 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt/
2026-03-04 21:47:00 +00:00
Mic
67189c4f6f
Translated using Weblate (Spanish)
Currently translated at 88.0% (426 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-03-04 21:46:59 +00:00
Mic
9242acd37a
Translated using Weblate (Esperanto)
Currently translated at 11.9% (58 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/eo/
2026-03-04 21:46:58 +00:00
Mic
8031e75867
Translated using Weblate (Italian)
Currently translated at 100.0% (484 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-03-04 21:46:57 +00:00
Mic
a48c315fea
Translated using Weblate (Romanian)
Currently translated at 15.9% (77 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ro/
2026-03-04 21:46:56 +00:00
Mic
6e4258f43b
Translated using Weblate (Swedish)
Currently translated at 98.1% (475 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-03-04 21:46:55 +00:00
Mic
4b097ce666
Translated using Weblate (French)
Currently translated at 98.1% (475 of 484 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-03-04 21:46:55 +00:00
Pieter de Bruin
bdcc54195a
Translated using Weblate (Dutch)
Currently translated at 0.2% (1 of 475 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/nl/
2026-03-04 21:46:54 +00:00
Pieter de Bruin
6cdfb489c8
Added translation using Weblate (Dutch) 2026-03-04 21:46:53 +00:00
mic
629688b6b8 guides and tutorial links added to the onboarding page 2026-03-04 22:46:33 +01:00
mic
1ea2d47e61 docs link added. welcome page link added. see #684 2026-03-04 22:35:55 +01:00
mic
9248249181 release notes updated 2026-03-04 21:53:54 +01:00
Mic
10af566931
Merge pull request #688 from micz/window_position_issue685
Window position issue 685
2026-03-04 21:50:43 +01:00
Mic
557f6741c3
Merge branch 'main' into window_position_issue685 2026-03-04 21:50:33 +01:00
mic
19c2258e69 added boundary check. see #685 2026-03-04 21:48:37 +01:00
mic
9fcfd2dad0 correctly using the chatgpt_win_save_position pref. see #685 2026-03-04 21:44:23 +01:00
mic
17572a573f default value changed for chatgpt_win_save_position. see #685 2026-03-04 21:41:02 +01:00
mic
83a147fdea var name fixed 2026-03-04 21:38:38 +01:00
mic
a401626805 version set to 4.0.2 2026-03-04 21:35:06 +01:00
mic
2485611f1f ... added to prompt name when asking for additional text 2026-03-04 21:34:04 +01:00
mic
d2c9797e16 race condition fixed 2026-03-04 21:29:04 +01:00
mic
7176880589 version set to 4.0.1_issue685_rev2 2026-03-03 23:30:35 +01:00
mic
eadc69d755 ai win positions options added to the prefs page. see #685 2026-03-03 23:30:14 +01:00
mic
60d4425f9b top and left are blank by default 2026-03-03 21:25:35 +01:00
mic
79712957a3 applyWindowPosition renamed to applyWindowPositionAndSize 2026-03-03 21:24:57 +01:00
mic
a90b20052a saving and using windows positions. see #685 2026-03-02 22:05:05 +01:00
mic
af6927c012 ai win position options added 2026-03-02 21:55:50 +01:00
mic
c5aa576229 version set to 4.0.1_issue685 2026-03-02 21:52:59 +01:00
mic
da70ea70c4 reference fixed 2026-02-27 22:18:41 +01:00
mic
61375d91b6 version set to 4.0.1. release notes updated 2026-02-27 22:12:53 +01:00
mic
7390764764 correctly handling additional text without placeholder. see #681 2026-02-27 22:11:05 +01:00
mic
7048164ee0 correctly appending the additional text when no placeholder is used in an API integration. see #681 2026-02-27 22:06:26 +01:00
mic
0300c873fd console.log debug statement commented out 2026-02-27 21:55:05 +01:00
Ronald Klarenbeek
7dfdc2ea54 Fix auto-summary: strip markdown formatting from AI responses 2026-02-27 15:28:56 +01:00
Mic
3c38b224a8
Update translations section in README.md 2026-02-26 23:22:50 +01:00
Mic
c8e6c0356f
Update commit message for Tom Select files 2026-02-26 22:37:52 +01:00
mic
698942c8ee tom-select issue message updated 2026-02-26 21:54:52 +01:00
mic
fc66a99722 tom-select update workflow added 2026-02-26 21:53:57 +01:00
mic
a95a8c7b50 added an emoji to the spam message 2026-02-25 21:44:42 +01:00
mic
1be31c5d37 VENDORS link updated. fixes #679 2026-02-25 21:33:55 +01:00
Ronald Klarenbeek
ca07cf5ed0 Fix duplicate 'Generating summary' when using manual mode button 2026-02-24 22:33:13 +01:00
yonie
c32563337e
Merge branch 'v4.0.0' into main 2026-02-24 22:19:31 +01:00
Ronald Klarenbeek
2df835d46e Fix auto-summary: inline styles, refresh button, and proper headerMessageId passing
- Move CSS inline as requested by maintainer (no external CSS file)
- Add fixed font sizing (14px) to prevent inheritance from email content
- Add refresh button to regenerate summaries
- Fix refresh bug: use summaryData.headerMessageId instead of message.headerMessageId
- Remove deleted message display script and CSS files
2026-02-24 22:17:47 +01:00
mic
28af4aac92 prepared for release 2026-02-24 21:35:51 +01:00
Mic
68ac804290
Merge pull request #678 from micz/v4.0.0
v4.0.0
2026-02-24 21:34:22 +01:00
Mic
6b583651a6
Merge branch 'main' into v4.0.0 2026-02-24 21:33:36 +01:00
mic
fb6b1d6b8e GEMINI.md renamed in CLAUDE.md 2026-02-24 21:26:22 +01:00
Mic
d3246417a9
Change cron schedule to check daily at 19:00 2026-02-24 21:03:39 +01:00
mic
49c5791d64 tom select updated to version 3.5.2. fixes #673 2026-02-23 22:15:35 +01:00
Mic
a355dfb6d6
Add 'enhancement' label to new issue creation
Added 'enhancement' label to the issue creation in the workflow.
2026-02-23 21:59:34 +01:00
mic
4f84da4256 Fixes ported from v3.8.5. 2026-02-23 21:55:10 +01:00
Mic
d95bd37fbf
Merge pull request #674 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-23 21:50:29 +01:00
Mic
c569795098
Translated using Weblate (Italian)
Currently translated at 100.0% (475 of 475 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-23 18:09:58 +00:00
Mic
6dc7b052c1
Translated using Weblate (German)
Currently translated at 100.0% (475 of 475 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-02-23 18:09:54 +00:00
Mic
e65699386c
Translated using Weblate (French)
Currently translated at 100.0% (475 of 475 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-02-23 18:09:50 +00:00
Andreas Pettersson
fe5f1db7b6
Translated using Weblate (Swedish)
Currently translated at 100.0% (475 of 475 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-23 18:09:48 +00:00
mic
c2e2336f4d Added "Antispam by ThunderAI" 2026-02-22 23:07:51 +01:00
mic
cad0cc59cc mzta-loading.svg moved in /images/ 2026-02-22 22:56:08 +01:00
mic
9894c2114c svg added when receiving text. see #671 2026-02-22 22:53:36 +01:00
mic
470b78ce90 checking for the correct placeholder before activating the no selection option in get calendar event. see #670 2026-02-22 22:39:59 +01:00
mic
a8a04df0a8 version set to 3.8.5. release notes updated 2026-02-22 22:26:10 +01:00
mic
3510636eb3 using sanitizeMailHeaders when needed. see #672 2026-02-22 22:23:24 +01:00
mic
e8e6c86be1 getMailHeader now returns always a string. sanitizeMailHeaders method added. see #672 2026-02-22 22:22:22 +01:00
mic
67a922ee02 onboarding improved 2026-02-22 09:35:42 +01:00
Mic
ba457adb98
Merge pull request #668 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-21 10:31:42 +01:00
Mic
6aca668d11
Translated using Weblate (German)
Currently translated at 100.0% (473 of 473 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-02-21 10:30:56 +01:00
Mic
0a8b2de10f
Merge pull request #667 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-21 08:30:24 +01:00
Andreas Pettersson
48b5dc0f75
Translated using Weblate (Swedish)
Currently translated at 100.0% (473 of 473 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-20 23:09:46 +01:00
mic
2e89ddef65 disablig btnNew when copying. see #598 2026-02-19 23:49:44 +01:00
Mic
04e3388fc8
Merge pull request #666 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-19 23:40:47 +01:00
Mic
3c45d136fd
Translated using Weblate (Italian)
Currently translated at 100.0% (473 of 473 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-19 23:40:14 +01:00
Mic
8380970da3
Translated using Weblate (French)
Currently translated at 100.0% (473 of 473 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-02-19 23:40:14 +01:00
Mic
a59d346d42
Translated using Weblate (French)
Currently translated at 100.0% (471 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-02-19 23:38:22 +01:00
mic
f0c9777ace thunderstats link added. see #663 2026-02-19 22:54:52 +01:00
Mic
bcc7a5f62b
Add reminder for VENDORS.md update in release check
Added a reminder to update the VENDORS.md file when updating Tom Select.
2026-02-19 22:30:59 +01:00
Mic
b2abad4b95
Enhance issue body with CDN links for Tom Select
Updated the issue body to include CDN links for the latest Tom Select version.
2026-02-19 22:29:52 +01:00
mic
fc47603f1f tomselect updated to 2.5.1 see #665 2026-02-19 22:28:04 +01:00
Mic
ec0a955feb
Rename workflow to Check Tom-Select Latest Release 2026-02-19 22:23:21 +01:00
mic
aa1cc73a1a added tom-select version check 2026-02-19 22:21:48 +01:00
Mic
45b1927490
Merge pull request #664 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-19 22:16:53 +01:00
bittin1ddc447d824349b2
9384c0574e
Translated using Weblate (Swedish)
Currently translated at 100.0% (471 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-19 16:09:46 +01:00
mic
3d3581dc26 version set to 4.0.0pre2 2026-02-18 23:08:44 +01:00
Mic
e302367f9c
Merge pull request #662 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-18 23:07:33 +01:00
Mic
f7e7367f60
Translated using Weblate (Italian)
Currently translated at 100.0% (471 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-18 23:06:55 +01:00
Mic
a071321055
Translated using Weblate (Italian)
Currently translated at 95.7% (451 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-18 22:58:29 +01:00
Mic
79bbcda6ca
Translated using Weblate (Italian)
Currently translated at 95.5% (450 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-18 22:58:29 +01:00
Mic
04b69a73c4
Translated using Weblate (Italian)
Currently translated at 92.7% (437 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-18 22:58:29 +01:00
mic
228e2b4102 en locales improved 2026-02-18 22:58:04 +01:00
mic
526be71348 en locales improved 2026-02-18 22:57:03 +01:00
mic
b36658153d en locale string fixed 2026-02-18 22:50:52 +01:00
mic
7e758a51e6 removed a method call for Thudnerbird 115 2026-02-17 23:19:58 +01:00
mic
b60e758802 removing auto translation from locales files 2026-02-17 22:55:26 +01:00
mic
2ba069e1be Merge remote-tracking branch 'origin/v4.0.0' into pr/yonie/579 2026-02-17 22:50:31 +01:00
Mic
4231df0259
Merge pull request #661 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-17 22:47:30 +01:00
Andreas Pettersson
c3f5e2be7e
Translated using Weblate (Swedish)
Currently translated at 100.0% (471 of 471 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-17 06:09:46 +00:00
mic
490427802d release notes updated 2026-02-16 22:31:14 +01:00
mic
296fcf21be if a message has already been checked for spam and the user asks for another check, the previous banne is removed. see #658 2026-02-16 22:30:20 +01:00
mic
b551692768 showing antispam errors on message. see #658 2026-02-16 22:25:44 +01:00
mic
dc5e23a4d5 correctly showing spam elaboration errors. see #658 2026-02-16 22:23:15 +01:00
mic
c4176ebfec saveError now returns the saved data. see #658 2026-02-16 22:22:39 +01:00
mic
bd72c45df2 saveError method added. see #658 2026-02-16 21:57:53 +01:00
mic
ae44596106 showing the processing status for the antispam filter. see #658 2026-02-16 21:54:17 +01:00
mic
25a979e9fb added methods and logic to save the processing status. see #658 2026-02-16 21:53:53 +01:00
Mic
519628b6f3
Merge pull request #659 from micz/summarize_code_improvements_issue631
Summarize code improvements
2026-02-15 22:13:10 +01:00
mic
fb83ad86fd info comment added 2026-02-15 22:04:37 +01:00
Mic
7fce9906b8
Merge pull request #657 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-15 18:17:25 +01:00
bittin1ddc447d824349b2
33901882cf
Translated using Weblate (Swedish)
Currently translated at 100.0% (470 of 470 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-15 17:09:46 +01:00
mic
ca2323ba88 processEmails now also does the summarize. see #631 2026-02-15 11:08:38 +01:00
mic
a7a17b7cb5 processEmails now accepts an obj as argument. see #631 2026-02-15 10:58:44 +01:00
mic
8fcd9fab69 release notes updated 2026-02-15 10:32:24 +01:00
mic
5c310d1cb0 ChatGPT Web Integration loading wait time option added. see #634 2026-02-15 10:30:22 +01:00
mic
ae26e9288b when using the same id in additional_text, the text is asked only once and then used in every occurrence. see #525 2026-02-14 23:23:07 +01:00
mic
5bbe379c0c release notes updated 2026-02-14 23:14:13 +01:00
mic
cac639e257 console.log debug statement commented out 2026-02-14 23:09:25 +01:00
Mic
d76f1d9d12
Merge pull request #656 from micz/multiple_additional_text_issue525
Multiple additional_text
2026-02-14 23:07:45 +01:00
Mic
17ec054e15
Merge branch 'v4.0.0' into multiple_additional_text_issue525 2026-02-14 23:07:24 +01:00
mic
d5d11e3c0c customDiv with multiple additional_text also when using the chatgpt web interface integration. see #525 #650 2026-02-14 23:04:08 +01:00
mic
0ac6ae6650 custom_text_array initialize fixed. see #525 2026-02-14 23:01:20 +01:00
mic
0740d94c79 focus on the additional_text textarea. see #525 2026-02-12 22:49:30 +01:00
mic
12206f0557 submit additional_text when pressing enter. see #525 fixes #654 2026-02-12 22:46:50 +01:00
mic
d00e242509 button margin added. see #525 #554 2026-02-12 22:41:16 +01:00
mic
28e3b65028 progressive numbers added. see #525 #554 2026-02-12 22:38:02 +01:00
mic
28afa0fc45 bigger form. see #525 #554 2026-02-12 22:29:24 +01:00
mic
774ffc2287 additional_text now printed on the form. see #525 #554 2026-02-12 22:10:12 +01:00
mic
41dbb5d009 # added to additional_text without id. see #525 #554 2026-02-12 21:57:52 +01:00
yonie
1630b7c071
Merge branch 'v4.0.0' into main 2026-02-12 21:10:43 +01:00
mic
e30d073bca handling multiple old {%additional_text%} placeholders. see #525 #554 #652 2026-02-11 23:10:33 +01:00
Mic
1f3691fab2
Merge pull request #653 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-11 22:52:05 +01:00
Christos Kanotidis
73d1795dc7
Translated using Weblate (Greek)
Currently translated at 100.0% (468 of 468 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-02-11 22:50:45 +01:00
Andreas Pettersson
c764a1ee2f
Translated using Weblate (Swedish)
Currently translated at 100.0% (468 of 468 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-11 22:50:44 +01:00
mic
ded59f14f7 checkPromptsConfigForPlaceholders updated. see #525 #554 2026-02-11 22:47:41 +01:00
mic
3213a71eba the additional text is now an array. see #525 #554 2026-02-11 21:55:04 +01:00
mic
c29b4b3352 userInput is now an array. see #525 #554 2026-02-11 21:45:48 +01:00
mic
b1282c9562 getPlaceholdersAdditionalTextArray method added. see #525 #554 2026-02-11 21:30:56 +01:00
mic
5fcf21a5e9 indentation fixed 2026-02-11 21:21:21 +01:00
Mic
378395d324
Fix link formatting for Swedish translation entry 2026-02-11 21:19:48 +01:00
Mic
4fecbe8087
Merge pull request #647 from bittin/main
Modify Swedish contributors in README.md
2026-02-11 21:18:15 +01:00
Mic
fa10a68337
Merge branch 'v4.0.0' into main 2026-02-11 21:17:33 +01:00
Mic
0e4ca443aa
Merge pull request #648 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-11 21:14:46 +01:00
bittin1ddc447d824349b2
fc578c42a4
Translated using Weblate (Swedish)
Currently translated at 100.0% (468 of 468 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-11 13:11:22 +01:00
Luna Jernberg
edd22529a2
Modify Swedish contributors in README.md
Updated Swedish translation contributors in README.
2026-02-11 06:16:19 +01:00
mic
34e8e242f6 hasPlaceholder and replacePlaceholder can now work with dynamic placeholders. see #525 #554 2026-02-10 21:42:26 +01:00
mic
2740fe3ee9 additional_text is now dynamic. see #525 #554 2026-02-10 21:36:59 +01:00
Mic
e4e356de0d version set to 3.8.4 and release notes updated 2026-02-10 18:28:17 +01:00
Mic
32aa24c88d saving the selection when selected and not when the user clicks the button to prevent recent changes in the ChatGPT web interface. see #646 2026-02-10 18:27:40 +01:00
mic
b4ae956b82 added an option to hide the spam filter info in the message. see #506 2026-02-08 22:30:07 +01:00
mic
0550077567 when closing the spam info panel, the report is deleted so the info is not displayed again. see #506 2026-02-08 22:22:00 +01:00
mic
7d843c0732 added an info about data persistence for the spam reports 2026-02-08 22:17:31 +01:00
mic
545b6db6d5 added a close button for the spam info. see #506 2026-02-08 22:10:44 +01:00
mic
3be8fad6db release notes updated 2026-02-08 22:01:52 +01:00
mic
45cc823171 showing the spam info on the current message when the elaboration is ended. see #506 2026-02-08 21:38:22 +01:00
mic
b713f4fd48 check fixed. see #506 2026-02-08 21:34:27 +01:00
mic
bf29673600 tom select udpated to 2.4.6. fixes #644 2026-02-08 21:14:07 +01:00
Mic
e7995952df
Merge pull request #645 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-08 21:10:49 +01:00
Andreas Pettersson
ef9a6a0e07
Translated using Weblate (Swedish)
Currently translated at 100.0% (465 of 465 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-08 20:09:43 +00:00
Mic
3bbe1a5351
Merge pull request #643 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-08 01:08:33 +01:00
Andreas Pettersson
500572fee1
Translated using Weblate (Swedish)
Currently translated at 100.0% (463 of 463 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-08 00:30:26 +01:00
mic
a940228a43 showing spam value. see #506 2026-02-08 00:10:39 +01:00
mic
10a26210d0 release notes updated 2026-02-06 23:52:45 +01:00
mic
ae010478ba prompt copy button added. see #598 2026-02-06 23:51:30 +01:00
mic
6c49008441 version set to 4.0.0pre1 2026-02-06 23:14:51 +01:00
Mic
4dda9fb5ff
Merge pull request #639 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-06 19:03:45 +01:00
Mic
7fb74d23e1
Translated using Weblate (Croatian)
Currently translated at 59.4% (274 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2026-02-06 19:01:57 +01:00
Mic
f5d278183b
Translated using Weblate (Greek)
Currently translated at 92.4% (426 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-02-06 19:01:57 +01:00
Mic
816118ed34
Translated using Weblate (German)
Currently translated at 92.4% (426 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-02-06 19:01:57 +01:00
Mic
454789149f
Translated using Weblate (Portuguese (Brazil))
Currently translated at 58.7% (271 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt_BR/
2026-02-06 19:01:56 +01:00
Mic
c9820bbb56
Translated using Weblate (Spanish)
Currently translated at 92.4% (426 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-02-06 19:01:56 +01:00
Mic
62ab34526c
Translated using Weblate (Czech)
Currently translated at 78.5% (362 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/cs/
2026-02-06 19:01:55 +01:00
Mic
9edae00b91
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 86.1% (397 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2026-02-06 19:01:55 +01:00
Mic
4b5768c990
Translated using Weblate (Italian)
Currently translated at 92.4% (426 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-02-06 19:01:54 +01:00
Mic
6b9ad17d7c
Translated using Weblate (Russian)
Currently translated at 85.0% (392 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2026-02-06 19:01:54 +01:00
Mic
4bf5016824
Translated using Weblate (Polish)
Currently translated at 61.8% (285 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2026-02-06 19:01:53 +01:00
Mic
3cf8d1a804
Translated using Weblate (Japanese)
Currently translated at 92.4% (426 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ja/
2026-02-06 19:01:53 +01:00
Mic
2a04c1af1f
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 62.6% (289 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-02-06 19:01:52 +01:00
Mic
954f1e3d8a
Translated using Weblate (French)
Currently translated at 92.4% (426 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-02-06 19:01:51 +01:00
Mic
cf7c58852e
Translated using Weblate (Swedish)
Currently translated at 97.6% (450 of 461 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-06 19:01:51 +01:00
bittin1ddc447d824349b2
c34fe07e66
Translated using Weblate (Swedish)
Currently translated at 100.0% (450 of 450 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-06 18:47:45 +01:00
Andreas Pettersson
d7321fb0a9
Translated using Weblate (Swedish)
Currently translated at 100.0% (449 of 449 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-06 18:47:45 +01:00
yonie
feaaac5e01
Merge branch 'v4.0.0' into main 2026-02-06 10:54:34 +01:00
Mic
829f87a510 saving the clipboard text also in the curr_prompt.text. see #362 2026-02-06 00:51:00 +01:00
Mic
6bbe521e12 saving also prompt_get_calendar_event_from_clipboard. see #362 2026-02-06 00:51:00 +01:00
Mic
f13ba84444 release notes updated 2026-02-06 00:51:00 +01:00
Mic
1844560027 adding a calendar event from clipboard. see #362 2026-02-06 00:42:00 +01:00
Mic
7c971218a3 gemini info updated 2026-02-06 00:29:00 +01:00
Mic
20d23cc951 release notes updated 2026-02-06 00:22:00 +01:00
Mic
632bf6c38a using calendar_no_selection option and updated the default prompt. see #518 2026-02-06 00:16:00 +01:00
Mic
db8cada6e6 mail_body_or_selected_text and mail_body_or_selected_html placeholders added. see #641 2026-02-06 00:08:00 +01:00
Mic
5a39f1e298 calendar_no_selection option added. see #641 2026-02-06 00:06:00 +01:00
Mic
6cb52e4403 await added to wait before saying that the new prompts are saved. 2026-02-06 00:00:00 +01:00
Mic
942c88d00e release notes updated 2026-02-05 23:58:00 +01:00
mic
fc67e4c221 added a dialog for prompt export. see #624 2026-02-05 23:43:25 +01:00
mic
fdba78bbcb yes no strings ids renamed 2026-02-05 23:36:56 +01:00
mic
d0fe616e42 preparePromptsForExport method now can exclude the api settings. see #624 2026-02-05 23:24:41 +01:00
Mic
ab3739521e
Fix typo in Perplexity API name 2026-02-04 23:08:08 +01:00
mic
e105ead516 release notes updated 2026-02-04 23:06:11 +01:00
mic
1fa6d2eed5 context menu items are always ordered alfabetically. see #630 2026-02-04 23:05:22 +01:00
mic
a44842af2f release notes updated 2026-02-04 22:51:29 +01:00
mic
f56e967e00 useless " removed 2026-02-04 22:45:13 +01:00
mic
d975e5c249 get_task has now the ability to specify a different API. see #498 2026-02-04 22:39:08 +01:00
Mic
b91b17789f
Update README with predefined OpenAI Compatible API configurations
Added predefined OpenAI Compatible API configurations for various APIs.
2026-02-04 22:22:01 +01:00
mic
f5dcebefb2 get_calendar_events has now the ability to specify a different API. see #498 2026-02-04 22:19:38 +01:00
mic
b632206d24 loadURLsPermissions method fixed 2026-02-04 22:19:01 +01:00
mic
d99d0829b3 release notes updated 2026-02-03 22:02:57 +01:00
mic
6ebc50b005 getCurrentIdentity method now uses also the folder owner to get the right identity for a reply. see #627 2026-02-03 22:00:55 +01:00
mic
5e58dc940f release notes updated 2026-02-03 21:33:07 +01:00
Mic
7fe0840296
Merge pull request #637 from micz/new_model_selector_issue603
New model selector
2026-02-03 21:30:53 +01:00
Mic
80c72301c6 tomselect css improved. see #603 2026-02-03 01:23:00 +01:00
Mic
2b8a9b9881 fixing border on startup on special prompts pages. see #603 2026-02-03 01:15:00 +01:00
Mic
73d6fdedc8 fixing border on startup. see #603 2026-02-03 01:13:00 +01:00
Mic
3e176f00b1 setTomSelectBorder method added. see #603 2026-02-03 01:13:00 +01:00
Mic
32e3e40cfc setting tomselect border red when empty. see #603 2026-02-03 01:05:00 +01:00
mic
ef3ea4a2c0 correctly setting the saved value at startup. see #603 2026-02-02 23:37:45 +01:00
mic
4409faf66a skipping input without id when restoring options. see #603 2026-02-02 23:16:11 +01:00
mic
dd9b116f0a tom select added. see #603 2026-02-02 22:59:24 +01:00
Mic
098528b323
Merge pull request #633 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-02-02 22:53:11 +01:00
Andreas Pettersson
3d6d325ca5
Translated using Weblate (Swedish)
Currently translated at 100.0% (448 of 448 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-02 22:52:11 +01:00
mic
11f00d99c9 Tom Select css added. see #603 2026-02-02 22:40:45 +01:00
mic
3427611162 Tom Select lib added. see #603 2026-02-02 22:06:58 +01:00
Hosted Weblate
6805efb22a
Update translation files
Updated by "Remove blank strings" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-02-02 21:05:05 +00:00
Hosted Weblate
1e245b3784
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/
2026-02-02 21:05:03 +00:00
Andreas Pettersson
ceb8432c69
Translated using Weblate (Swedish)
Currently translated at 100.0% (447 of 447 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-02-02 21:05:01 +00:00
Müslüm Barış Korkmazer
1b66d6cc1f
Translated using Weblate (Turkish)
Currently translated at 1.3% (6 of 447 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/tr/
2026-02-02 21:05:00 +00:00
Müslüm Barış Korkmazer
5b16e51f89
Added translation using Weblate (Turkish) 2026-02-02 21:04:59 +00:00
Anonymous
4318f09b10
Translated using Weblate (Polish)
Currently translated at 65.9% (285 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2026-02-02 21:04:58 +00:00
Anonymous
c0c29e6581
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 67.8% (293 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hans/
2026-02-02 21:04:57 +00:00
Anonymous
07da54b3d2
Translated using Weblate (Norwegian Bokmål)
Currently translated at 0.0% (0 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/nb_NO/
2026-02-02 21:04:56 +00:00
Anonymous
06e42a841b
Translated using Weblate (Esperanto)
Currently translated at 13.4% (58 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/eo/
2026-02-02 21:04:55 +00:00
Anonymous
ffafa2b796
Translated using Weblate (Bulgarian)
Currently translated at 15.5% (67 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/bg/
2026-02-02 21:04:54 +00:00
Anonymous
30b94e2b49
Translated using Weblate (Romanian)
Currently translated at 17.8% (77 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ro/
2026-02-02 21:04:53 +00:00
Anonymous
b3be32106d
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 93.2% (403 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2026-02-02 21:04:52 +00:00
Anonymous
d87694a45b
Translated using Weblate (Czech)
Currently translated at 85.1% (368 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/cs/
2026-02-02 21:04:51 +00:00
Anonymous
f526684beb
Translated using Weblate (Russian)
Currently translated at 92.1% (398 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2026-02-02 21:04:49 +00:00
Maurizio Domba Cerin
92063056c7
Translated using Weblate (Croatian)
Currently translated at 63.4% (274 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2026-02-02 21:04:48 +00:00
Anonymous
656def1b1c
Translated using Weblate (Croatian)
Currently translated at 63.4% (274 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2026-02-02 21:04:47 +00:00
Anonymous
b5cf8072d5
Translated using Weblate (Slovak)
Currently translated at 0.0% (0 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sk/
2026-02-02 21:04:46 +00:00
Anonymous
903cac77dc
Translated using Weblate (Portuguese (Brazil))
Currently translated at 62.7% (271 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt_BR/
2026-02-02 21:04:45 +00:00
Anonymous
3d3e1aa336
Translated using Weblate (Portuguese)
Currently translated at 13.4% (58 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt/
2026-02-02 21:04:44 +00:00
Anonymous
b2a5b32f1d
Translated using Weblate (Hungarian)
Currently translated at 1.1% (5 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hu/
2026-02-02 21:04:42 +00:00
mic
50eaa3d28d release notes updated 2026-02-02 22:03:51 +01:00
mic
db8691e017 asking the <all_urls> permission if the server is hosted on localhost. see #524 2026-02-02 21:43:15 +01:00
mic
a720ad31ba readded <all_urls> permission. see https://github.com/micz/ThunderAI/issues/524#issuecomment-3837352541 2026-02-02 21:32:54 +01:00
mic
b37df075ae cors info labels updated. see #524 2026-02-01 23:56:41 +01:00
mic
04150fcbbf updating cors warning visibility when giving permission. see #524 2026-02-01 23:52:35 +01:00
mic
2bc292e414 opanai comp api direct host permission request added. see #524 2026-02-01 23:48:40 +01:00
mic
2d93672d8f ollama direct host permission requeest added. see #524 2026-02-01 23:27:29 +01:00
mic
29bdd248b1 prepareOriginURL added. see #524 2026-02-01 22:46:35 +01:00
mic
ccdfb39f43 strict_min_version reverted to 140.0. see #616 2026-02-01 22:28:19 +01:00
mic
e20e57381f requestSitePermission method added. see #524 2026-01-30 22:58:11 +01:00
mic
33f39fb3ba strict_min_version set to 140.*. see #616 2026-01-30 22:56:21 +01:00
mic
cc3542a13e all_urls permission removed. see #524 2026-01-30 22:53:44 +01:00
mic
819e0c5655 release notes updated 2026-01-30 22:45:52 +01:00
mic
f58c122c16 summarize special prompt "reset to default" buttons disabling logic fixed. see #615 2026-01-30 22:43:09 +01:00
mic
5348cdc25e removed all the 115 and 128 related methods and calls. see #616 2026-01-30 22:31:19 +01:00
mic
bae2e0f012 issue template version examples updated. see #616 2026-01-30 22:25:34 +01:00
mic
7bab6c7b78 115 listener call removed. see #616 2026-01-30 22:25:00 +01:00
mic
6463e180af tb115 segmenter removed. see #616 2026-01-30 22:24:17 +01:00
mic
72737d538b strict_min_version set to 140.0. see #616 2026-01-30 22:22:59 +01:00
mic
310dbf8818 release notes updated 2026-01-30 22:21:37 +01:00
Mic
bd12e430bd
Merge pull request #628 from micz/thread_summary_issue615
Thread summary issue 615
2026-01-30 22:11:36 +01:00
Mic
0b7e81cd7b GEMINI.MD file added 2026-01-30 22:09:04 +01:00
Mic
3ba98c7d90 Removed the spamfilter_context_menu and add_tags_context_menu options and always show the context menu when the corresponding feature is active. See #609 2026-01-29 23:45:00 +01:00
Mic
f489e65483 correctly adding context menu item for summarize when activating the feature. fixes #626 2026-01-29 23:36:00 +01:00
mic
63b80d4e42 summarize icon added. see #615 2026-01-29 23:29:27 +01:00
Mic
fca6558133
Merge pull request #597 from gdkrmr/gk/thread_summary
thread summary
2026-01-29 23:10:52 +01:00
mic
4576549bab version set to 4.0.0 2026-01-29 22:53:33 +01:00
Mic
5fc77c395e
Update translations section in README.md 2026-01-23 21:01:47 +01:00
Mic
607708930f
Add Japanese translation contributor to README 2026-01-22 23:06:27 +01:00
mic
84c003f2a6 LANG.md updated 2026-01-22 23:01:50 +01:00
mic
bf9e37dda1 release notes udpated 2026-01-22 22:51:13 +01:00
Mic
150fbced3d
Merge pull request #622 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-22 22:47:46 +01:00
mic
04afa25aa4 version set to 3.8.3. release notes updated 2026-01-22 22:47:19 +01:00
mic
facc0bce74 resetApiSettings method added. showing the reset button also in the new prompt form. see #623 2026-01-22 22:38:30 +01:00
mic
6484e48964 correctly not setting the conn_type calue for new prompts. See #623 2026-01-22 22:37:34 +01:00
taichi ito (watya)
6afa053917
Translated using Weblate (Japanese)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ja/
2026-01-22 06:06:05 +01:00
taichi ito (watya)
09b38776f2
Translated using Weblate (Japanese)
Currently translated at 0.0% (0 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ja/
2026-01-22 01:48:07 +01:00
taichi ito (watya)
22296d37ac
Added translation using Weblate (Japanese) 2026-01-22 01:44:42 +01:00
mic
39a5c3367c typo fixed 2026-01-20 23:50:51 +01:00
mic
a228a316b9 version set to 3.8.2. release notes updated 2026-01-20 23:49:19 +01:00
mic
a888370fd2 correctly saving the need_custom_text status with a direct edit on the page. see #621 2026-01-20 23:48:07 +01:00
mic
0041a8a6a4 correctly saving the enabled status with a direct edit on the page. see #621 2026-01-20 23:43:46 +01:00
mic
3180898dce var name fixed. see #621 2026-01-20 23:37:12 +01:00
Mic
5e57ee19d0 version set to 3.8.1. release notes updated 2026-01-20 13:39:24 +01:00
Mic
04d12594a7 openai api fixed. see #620 2026-01-20 13:37:35 +01:00
Mic
cc7b8d1640 added a commented out console.log debug line 2026-01-20 13:37:20 +01:00
mic
272dc59f00 Version set to 3.8.0. Release notes updated. 2026-01-16 22:34:47 +01:00
Mic
99bde03a73
Merge pull request #617 from micz/v3.8.0
v3.8.0
2026-01-16 22:32:11 +01:00
Mic
1d04aa4941
Merge branch 'main' into v3.8.0 2026-01-16 22:31:53 +01:00
mic
1d83c3a8c0 correctly handling empty body with no placeholders. see #614 2026-01-16 22:29:34 +01:00
Guido Kraemer
f6fcaac0bb update prompts 2026-01-16 15:09:47 +01:00
Guido Kraemer
b247dad80f adapt code copied from add_tags 2026-01-16 14:22:07 +01:00
Guido Kraemer
7202b5a3e2 fix prompt names 2026-01-16 14:21:35 +01:00
Guido Kraemer
cb6c93625b correct prompt naming 2026-01-16 13:39:22 +01:00
Guido Kraemer
f147a0453b remove summarize_context_menu option in favor of summarize option 2026-01-16 12:57:06 +01:00
Guido Kraemer
90dcf8437b remove stray console logging 2026-01-16 12:56:35 +01:00
Guido Kraemer
8679e1cb08 remove checking for non-optional permission 2026-01-16 12:55:56 +01:00
Mic
6e09bffaf1
Merge pull request #612 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-14 21:59:20 +01:00
Christos Kanotidis
bd1ea03f78
Translated using Weblate (Greek)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-01-14 19:41:02 +01:00
Guido Kraemer
51c81418a3 handle disabling summarize options button 2026-01-10 23:00:20 +01:00
Guido Kraemer
d601121852 better descriptions for prompts 2026-01-10 22:59:26 +01:00
Guido Kraemer
30a7de3756 better explanation 2026-01-10 21:22:11 +01:00
Guido Kraemer
c261c1da90 fix bug 2026-01-10 21:22:11 +01:00
Guido Kraemer
c6bf2edba5 allow placeholders in other summarize prompts 2026-01-10 21:22:11 +01:00
Guido Kraemer
24edcc09e6 make some variables const 2026-01-10 21:22:11 +01:00
Guido Kraemer
66cc35746f move email separators to extra prompt field 2026-01-10 21:22:11 +01:00
Guido Kraemer
3d2c2b9320 add customizable model options for summarize 2026-01-10 21:22:11 +01:00
Guido Kraemer
c3e27f0356 Fix malformed label closing tag in options page 2026-01-10 21:22:11 +01:00
Guido Kraemer
7595c70a38 Implement summarization internals 2026-01-10 21:22:11 +01:00
Guido Kraemer
f29d8337ad WIP: Add Summarize context menu action and handler 2026-01-10 21:22:11 +01:00
Guido Kraemer
fe427c29ee Add Email Template Editor to Summarize Panel 2026-01-10 21:22:11 +01:00
Guido Kraemer
7eb9a2cf56 fixes saving of summarize prompt 2026-01-10 21:22:11 +01:00
Guido Kraemer
2c07aa6336 Remove unused imports from mzta-summarize.js 2026-01-10 21:22:11 +01:00
Guido Kraemer
8abb7e349b Add summarize prompt to specialPrompts 2026-01-10 21:22:11 +01:00
Guido Kraemer
02787e2f25 Fix context menu ID typos 2026-01-10 21:22:11 +01:00
Guido Kraemer
4ab6da2faf change all "summary" -> "summarize" 2026-01-10 21:22:11 +01:00
Guido Kraemer
050a3fd1f7 Add MZTA summary page 2026-01-10 21:22:11 +01:00
Guido Kraemer
84a65acd8f resolve rebase conflicts 2026-01-10 21:22:11 +01:00
mic
12ba436f4d hiding api keys in the prompt log 2026-01-09 23:37:35 +01:00
mic
de7ba70993 debug log improved. now commented out 2026-01-09 23:32:55 +01:00
mic
0206e421ae missing spaces added 2026-01-09 23:11:38 +01:00
mic
aa0fd97563 fix query selector 2026-01-09 22:52:41 +01:00
yonie
ce33cc178a
Merge branch 'v3.8.0' into main 2026-01-09 08:26:52 +01:00
Mic
bca2b0e62d
Merge pull request #608 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-06 22:27:18 +01:00
Christos Kanotidis
8c2ece5520
Translated using Weblate (Greek)
Currently translated at 97.9% (423 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2026-01-06 22:26:40 +01:00
yonie
0ceaf79aa7
Merge branch 'v3.8.0' into main 2026-01-06 17:28:45 +01:00
mic
85ffca5579 version set to 3.7.9. release notes updated 2026-01-06 12:08:56 +01:00
mic
a22398a354 Gett the completion of the job on ChatGPT Web. Fixes #607 2026-01-06 12:07:31 +01:00
mic
5dc2451c3c no concurrency runs of the prerelease workflow 2026-01-06 11:46:30 +01:00
Mic
b8feae50c2
Merge pull request #606 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-06 11:39:29 +01:00
Andreas Pettersson
927ef5af37
Translated using Weblate (Swedish)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-06 11:38:33 +01:00
mic
4bf08b0d9b release notes updated 2026-01-05 16:34:29 +01:00
mic
d9bded0bb7 sv translation added 2026-01-05 16:34:11 +01:00
Mic
d2833ed62c
Merge pull request #605 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-05 16:29:38 +01:00
Andreas Pettersson
4c68ad0de2
Translated using Weblate (Swedish)
Currently translated at 98.1% (424 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-05 16:28:35 +01:00
Andreas Pettersson
d51d907e84
Translated using Weblate (Swedish)
Currently translated at 96.9% (419 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:45:06 +01:00
Mic
d73dc3f076
Translated using Weblate (German)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2026-01-04 23:45:00 +01:00
Andreas Pettersson
02ea92938e
Translated using Weblate (Swedish)
Currently translated at 96.7% (418 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:44:59 +01:00
Andreas Pettersson
e418e848a9
Translated using Weblate (Swedish)
Currently translated at 89.1% (385 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:30:32 +01:00
Thomas Hegghammer
daaaaf7e2d
Added translation using Weblate (Norwegian Bokmål) 2026-01-04 23:30:31 +01:00
Andreas Pettersson
dacfc6377b
Translated using Weblate (Swedish)
Currently translated at 62.2% (269 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:30:30 +01:00
Andreas Pettersson
b3af371a6b
Translated using Weblate (Swedish)
Currently translated at 49.5% (214 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:30:29 +01:00
Andreas Pettersson
71ea10dd55
Translated using Weblate (Swedish)
Currently translated at 47.4% (205 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:30:28 +01:00
Andreas Pettersson
b0536bea27
Translated using Weblate (Swedish)
Currently translated at 47.2% (204 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-04 23:30:27 +01:00
mic
4aeab58a35 release notes updated 2026-01-04 23:29:50 +01:00
mic
1779a30c84 getConnectionType call updated. see #604 2026-01-04 17:47:53 +01:00
mic
d0fac711fb getConnectionType improved. see #604 2026-01-04 17:43:39 +01:00
mic
303bd86bac clearing spamfilter_connection_type pref when needed 2026-01-04 17:33:20 +01:00
mic
f478516d60 clearing add_tags_connection_type pref when needed 2026-01-04 17:31:06 +01:00
mic
1a28f5efba log improved 2026-01-04 17:30:39 +01:00
mic
4e1b20026b version set to 3.8.0pre4 2026-01-04 17:14:28 +01:00
mic
1b5c904030 the custom prompts reset button is cearling all specific api settings in the prompt. see #601 2026-01-04 17:12:28 +01:00
yonie
64069958a2
Merge branch 'v3.8.0' into main 2026-01-04 16:02:44 +01:00
mic
fd97d302ef improved the uniqueness of the tag IDs 2026-01-03 23:50:19 +01:00
mic
57f1d637ff added two commented debug lines 2026-01-03 23:43:57 +01:00
mic
07477b6d38 using specific api configuration in special prompts 2026-01-03 23:36:47 +01:00
Mic
f92c515978
Merge pull request #602 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-03 23:14:50 +01:00
Andreas Pettersson
0b002e902c
Translated using Weblate (Swedish)
Currently translated at 45.6% (197 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2026-01-03 23:11:41 +01:00
mic
fdc8d0920b api_model removed. see #102 2026-01-03 23:10:31 +01:00
mic
441a2d5835 info comment updated. see #102 2026-01-03 23:09:33 +01:00
mic
b32ce4f756 copyright date updated to 2026 2026-01-03 23:04:01 +01:00
mic
def2cb2372 addeventlistener commented out 2026-01-03 00:22:24 +01:00
mic
b558fc2ed2 fix for clickable checkbox labels 2026-01-03 00:20:41 +01:00
Mic
d5dcd23272
Merge pull request #599 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-03 00:08:48 +01:00
mic
97b016ab63 refining how to handle specific api settings. see #102 2026-01-03 00:03:48 +01:00
Ronald Klarenbeek
af2ae047dd fix en locale structure breaking the extension 2026-01-02 23:52:08 +01:00
Ronald Klarenbeek
e5f5d08582 feat(i18n): add auto summary strings for cs, ru, zh_Hans, and zh_Hant locales
- Add new translation strings for auto summary feature
- Include title, generating, failed, and prompt messages
- Remove unnecessary description fields from en locale
- Add missing auto summary preference strings for zh_Hant locale
2026-01-02 23:40:35 +01:00
Ronald Klarenbeek
90efefd363 feat(i18n): add auto summary feature strings for multiple locales
- Add new translation strings for auto summary feature in bg, de, el, eo, es, fr, hr, hu, it, pl, pt-br, pt, ro, sk, and sv locales
- Include preference options, title, status messages, and prompt templates
- Remove unnecessary description fields from existing strings
2026-01-02 23:26:17 +01:00
Mic
68c6145828
Translated using Weblate (Italian)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2026-01-02 22:50:46 +01:00
Mic
2cbc8c2d0e
Translated using Weblate (French)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2026-01-02 22:50:45 +01:00
Mic
7bafb035b2
Translated using Weblate (Spanish)
Currently translated at 100.0% (432 of 432 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-01-02 22:50:45 +01:00
Ronald Klarenbeek
3f63cc3580 feat(summary): implement new configuration model, fix multilingual support and fix error display
- Introduce localized UI strings for auto-summary feature across multiple languages
- Standardize error messages and implement consistent error propagation
- Refactor summary generation to align with v3.8.0 settings architecture
- Enhance user experience with localized loading and error states
- Improve code reliability through structured error handling and cleanup
2026-01-02 22:42:46 +01:00
mic
01142fb582 correctly hiding and showing the chatgpt additional prop toggle. see #102 2026-01-02 22:35:24 +01:00
mic
c7c5d0c594 correctly handling chatgpt additional props show. see #102 2026-01-02 22:30:44 +01:00
mic
1362da944e correctly using the toggleApiPropertiesShow method. see #102 2026-01-02 22:10:29 +01:00
Ronald Klarenbeek
a34394d442 feat(i18n): add auto summary preference strings for es, fr, and sv locales 2026-01-02 21:57:51 +01:00
Ronald Klarenbeek
ea402a688b Merge upstream v3.8.0 changes, preserving auto_summary_enabled setting 2026-01-02 21:05:52 +01:00
mic
82629fb495 missing strings fixed. see #102 2026-01-02 18:15:44 +01:00
mic
00e415b40f italic removed. see #102 2026-01-02 18:08:01 +01:00
mic
9840b0f265 labels fixed. see #102 2026-01-02 18:07:08 +01:00
mic
c1368fdf44 various css fixses. see #102 2026-01-02 18:04:29 +01:00
mic
94d1647c35 correctly showing the specific api on confirm. see #102 2026-01-02 17:51:13 +01:00
mic
622d9a9c82 specific api show improved. see #102 2026-01-02 17:43:57 +01:00
mic
a9a898ec29 correctly setting the show text. see #102 2026-01-02 17:35:44 +01:00
mic
b80bcd35bb a string added to i18n 2026-01-02 17:32:36 +01:00
Mic
2239f76d5e
Merge pull request #595 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2026-01-02 17:21:41 +01:00
Gerardo Sobarzo
9738350477
Translated using Weblate (Spanish)
Currently translated at 100.0% (431 of 431 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2026-01-02 15:52:32 +01:00
mic
b3ddbc85dd css fix. see #102 2026-01-02 12:35:37 +01:00
mic
3ebbaf184b reset button added. see #102 2026-01-02 12:33:53 +01:00
mic
ae83e3284e correctyl updating the UI wornings. see #102 2026-01-02 12:17:10 +01:00
mic
c18a517b82 css fix. see #102 2026-01-02 12:13:00 +01:00
mic
163bbdc055 now loading default API settings if needed. see #593 2026-01-02 12:09:00 +01:00
mic
56362266e2 the api settings table container is now in the html page. see #102 2026-01-02 10:21:47 +01:00
mic
92fba4a1b3 comments improved 2026-01-02 10:14:53 +01:00
mic
b796b3deec api settings in new form are now defined in the html page. see #102 2026-01-02 10:13:55 +01:00
mic
07f5c699a4 useless switch converted to if 2026-01-02 10:04:07 +01:00
mic
a96e87e95a missing string added 2026-01-02 10:02:34 +01:00
mic
33fdd0cc9b correctyl showing and hiding api settings elements. see #102 2026-01-02 09:54:04 +01:00
mic
0fb95121a4 css correctly imported. labels width fixed. see #102 2026-01-02 09:44:50 +01:00
mic
7f2c3b422f working on custom prompt ui. see #102 2026-01-01 22:15:01 +01:00
mic
1d8e955ba7 mzta_specialCommand class improved 2026-01-01 21:52:01 +01:00
Mic
df95e56ebb
Merge pull request #592 from micz/api_at_prompt_level
API settings at prompt level
2026-01-01 21:44:13 +01:00
mic
e3d927ab29 specific integration settings are now saved at prompt level. see #102 2026-01-01 21:41:48 +01:00
mic
9429395030 maxtokens is parsed as an int 2026-01-01 21:38:30 +01:00
mic
1b1143e6e3 saving custom prompts api settings 2026-01-01 16:30:10 +01:00
mic
0eaeec9e9f fixes to work with the custom prompts page. see #102 2026-01-01 16:17:10 +01:00
mic
3e05f0b551 Working on a first version... See #102 2026-01-01 16:00:31 +01:00
mic
2357886693 processEmails updated to use the new dyamic settings 2026-01-01 15:17:55 +01:00
mic
d39771f02c some comments translated to english 2026-01-01 15:14:30 +01:00
Mic
8735252ad1
Merge pull request #591 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-12-30 22:23:08 +01:00
Mic
675b4b296c
Translated using Weblate (French)
Currently translated at 99.7% (430 of 431 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-12-30 22:22:14 +01:00
Gerardo Sobarzo
daaf5dfbe0
Translated using Weblate (Spanish)
Currently translated at 73.5% (317 of 431 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2025-12-30 22:13:19 +01:00
Andreas Pettersson
0512a83bd9
Translated using Weblate (Swedish)
Currently translated at 5.3% (23 of 431 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/sv/
2025-12-30 22:13:18 +01:00
Andreas Pettersson
b07de999c2
Added translation using Weblate (Swedish) 2025-12-30 22:13:18 +01:00
mic
6c79e220ac release notes updated 2025-12-30 22:13:05 +01:00
mic
36e7c26e96 version set to 3.8.0pre3 2025-12-30 22:09:45 +01:00
mic
ffb7b8d3c1 red border if the temperature value is not a number. see #582 2025-12-30 22:05:37 +01:00
mic
96657611b8 text udpated 2025-12-29 23:09:47 +01:00
mic
5bd00fd64b release notes updated 2025-12-29 22:45:30 +01:00
Mic
1fd82731ff
Merge pull request #590 from micz/dynamic_api_settings
Dynamic API Settings
2025-12-29 22:39:35 +01:00
mic
168dd339a0 spamfilter updated to use the new dynamic settings 2025-12-29 22:28:30 +01:00
mic
154a0a981b option-input-specific removed 2025-12-29 22:25:15 +01:00
mic
285ee3a79e the controller.js is now dynamic 2025-12-29 22:22:45 +01:00
mic
f47b12946a workers updated to use the new dynamic settings 2025-12-29 22:03:45 +01:00
mic
5893ee668c fixed chatgpt_store and chatgpt_temperature var names 2025-12-29 22:02:33 +01:00
mic
a436bd16b2 chatgpt_api var names fixed 2025-12-29 21:58:09 +01:00
mic
3816d89bd0 dynamically saving special prompts api settings 2025-12-29 21:41:31 +01:00
mic
2dcb661368 add_tags updating settings values from the special prompt 2025-12-29 21:39:40 +01:00
mic
a7d42530fc improved isAPIKeyValue method 2025-12-29 21:31:31 +01:00
mic
39a4cab4e2 all integration settings are saved separately for the special prompts 2025-12-29 12:09:31 +01:00
mic
3ef13eec9b using a dynamic generation for all integration settings 2025-12-29 11:20:11 +01:00
mic
d14489e365 release notes updated 2025-12-28 23:35:42 +01:00
mic
23a9aa1905 es lang added 2025-12-28 23:35:32 +01:00
mic
3adb5faab2 working on a dynamic special prompts settings managing system 2025-12-28 23:27:27 +01:00
Mic
900c0e3e49
Merge pull request #589 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-12-28 23:03:52 +01:00
Gerardo Sobarzo
6b0ef777e1
Translated using Weblate (Spanish)
Currently translated at 64.7% (276 of 426 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2025-12-28 22:58:18 +01:00
mic
12e846739e special prompts temperature is now saved per prompt. see #561 2025-12-28 22:33:25 +01:00
mic
17f73936ea release notes updated 2025-12-28 22:32:10 +01:00
mic
ef940e40b5 NaN check fixed 2025-12-28 21:45:05 +01:00
mic
7f4f3e6fe7 claude temperature check fixed 2025-12-28 21:36:31 +01:00
mic
7803fc3006 openai worker init improved 2025-12-28 21:32:58 +01:00
mic
6b7160bde5 ollama worker init improved 2025-12-28 21:32:24 +01:00
mic
17fe989dec claude worker init improved 2025-12-28 21:31:17 +01:00
mic
c7a43bbb21 gemini worker init improved 2025-12-28 21:30:03 +01:00
mic
7c3d3458c8 openai comp worker init fixed 2025-12-28 21:28:54 +01:00
mic
8270f725ae id fixed 2025-12-28 21:25:02 +01:00
mic
69516bd056 temperature added to OpenAI Compatibile API. see #575 2025-12-28 21:23:09 +01:00
mic
17a0aeb632 temperature added to Ollama API. see #574 2025-12-28 21:12:08 +01:00
mic
78b691271f many fixes in using the temperature parameter. see #571 #572 #573 2025-12-27 22:56:57 +01:00
mic
dfa4da5b2e temperature added to Open AI API. see #571 2025-12-27 22:40:51 +01:00
mic
0408f6f45e release notes updated 2025-12-27 22:30:54 +01:00
mic
6ab3de07fe config info in the webchat API improved for all integrations 2025-12-27 22:27:59 +01:00
mic
c2d99076b2 temperature added to the Claude API. see #573 2025-12-27 22:21:20 +01:00
mic
f95fbeb00e temperature added to Google Gemini. see #572 2025-12-26 23:35:42 +01:00
mic
3c089fc04e temperature added to the google gemini class. see #572 2025-12-26 23:16:56 +01:00
mic
de7a2ca831 correctly handling dynamic palceholders when autocompleting. see #553 2025-12-26 23:03:23 +01:00
mic
c9b0e39433 property name fixed. see #553 2025-12-26 22:56:36 +01:00
mic
01df96d0c7 using mapPlaceholderToSuggestion. see #553 2025-12-26 22:52:34 +01:00
mic
cc2d3b8e5a mapPlaceholderToSuggestion exported directly. see #553 2025-12-26 22:49:26 +01:00
mic
385241efb3 mapPlaceholderToSuggestion method added. see #553 2025-12-26 22:48:09 +01:00
mic
5468928673 console.log debug lines commented out 2025-12-26 22:32:18 +01:00
Ronald Klarenbeek
bd66a37d35 feat(summary): add auto-summary preference for message previews
- Add new preference option to enable automatic AI summarization
- Update all localization files with new preference text
- Implement preference check in message display script
- Add default preference setting in options configuration
- Include preference toggle in options UI

This adds a user-configurable option to automatically generate and display AI summaries when viewing email messages, with appropriate warnings about data transmission to AI services.
2025-12-26 22:20:13 +01:00
Ronald Klarenbeek
dcbf9d3dcd feat(summary): add AI-powered message summary feature
Add new ThunderAI summary functionality that generates concise summaries
for email messages using the existing ThunderAI infrastructure. Includes
a new content script that creates a summary pane in the message display,
associated CSS styling, and backend integration for AI summary generation.

The feature shows a loading indicator while generating the summary and
falls back to showing truncated message content if the AI generation fails.
2025-12-26 20:39:30 +01:00
mic
dc6f4f2d5b version set to 3.8.0pre2 2025-12-26 12:13:07 +01:00
mic
542deb25a1 release notes updated 2025-12-26 12:12:53 +01:00
Mic
d34597ff4d
Merge pull request #576 from micz/mail_headers_issue527
Mail headers with dynamic placeholders
2025-12-26 12:10:38 +01:00
mic
5e8015161b correctly substituting text for a dynamic placeholder see #527 2025-12-26 12:09:26 +01:00
mic
049b88302a if it's async, you have to wait..... 2025-12-26 11:51:34 +01:00
mic
f22482d083 console.log debug line added 2025-12-26 11:49:36 +01:00
mic
5521945d70 fixed wrong line modified 2025-12-26 11:47:24 +01:00
mic
06c13a4f81 using the correct dynamic id for the substitution. see #527 2025-12-26 11:47:05 +01:00
mic
633f0dc3e2 getMailHeader method added. see #527 2025-12-26 11:45:20 +01:00
mic
61c7edc544 var name fixed. see #527 2025-12-26 11:45:05 +01:00
mic
7a6927ceec dynamic placeholder methods added. see #527 2025-12-26 11:37:25 +01:00
mic
1311f56825 version set to 3.8.0pre1 2025-12-24 00:09:34 +01:00
mic
936f225adf OpenAI class for responses constructor fixed. see #407 2025-12-24 00:08:18 +01:00
Mic
3e7f67b698 removing commented line 2025-12-22 23:55:00 +01:00
Mic
3c5b0aa02a release notes updated 2025-12-22 23:55:00 +01:00
Mic
9921632e6e Merge branch 'openai_responses_api' into v3.8.0 2025-12-22 23:55:00 +01:00
Mic
85a473dd3d include fix. see #407 2025-12-22 23:55:00 +01:00
Mic
f6141f8852 old openai api files removed. see #407 2025-12-23 00:29:00 +01:00
Mic
713415c1d2 now using the openai responses API. see #407 2025-12-23 00:29:00 +01:00
mic
87eef12efd release notes updated 2025-12-22 23:48:03 +01:00
mic
e0f5f263ed model filtering improved 2025-12-22 23:46:58 +01:00
mic
65ee959f0d improved openai responses see #407 2025-12-22 23:46:33 +01:00
mic
aa33d87390 Merge branch 'openai_responses_api' of github.com:micz/ThunderAI into openai_responses_api 2025-12-22 23:37:42 +01:00
Mic
8e04393c19 implemented the new api call, no response elaboration yet 2025-12-22 23:37:05 +01:00
mic
c00e784059 version set to 3.8.0 2025-12-22 23:33:31 +01:00
Mic
b5741c61bb
Add Greek language support to README 2025-12-18 22:46:49 +01:00
mic
4c20eb8db9 Greek translation added. See #566 2025-12-18 22:23:55 +01:00
mic
e1fda7bf12 version set to 3.7.8, release notes updated 2025-12-18 22:23:14 +01:00
Mic
d2f1771800
Merge pull request #567 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-12-18 22:21:08 +01:00
Christos Kanotidis
b374d53729
Translated using Weblate (Greek)
Currently translated at 100.0% (423 of 423 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/el/
2025-12-18 10:53:34 +01:00
Christos Kanotidis
6a314476b2
Added translation using Weblate (Greek) 2025-12-17 16:55:45 +01:00
mic
9825f1fc96 typo fixed 2025-12-14 22:22:05 +01:00
mic
3156d4020b release notes updated 2025-12-14 22:19:35 +01:00
mic
b540e0ba73 JSON parsing lines error handling improved in APIs. See #550 2025-12-14 22:19:04 +01:00
Mic
29891df80e
Merge pull request #562 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-12-14 21:51:17 +01:00
Mic
eddef1e904
Translated using Weblate (Polish)
Currently translated at 67.3% (285 of 423 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2025-12-11 12:22:01 +01:00
mic
9ac80030df fixing OpenRouter first line. see #550 2025-12-08 16:33:58 +01:00
mic
f57b855337 debug console.log statement commented 2025-12-08 16:22:45 +01:00
Mic
10088cfdad
Merge pull request #559 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-12-08 16:10:15 +01:00
Mic
2283c8231b
Translated using Weblate (German)
Currently translated at 100.0% (423 of 423 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-12-08 16:09:54 +01:00
Mic
4ee92bc8c2
Translated using Weblate (French)
Currently translated at 100.0% (423 of 423 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-12-08 16:09:54 +01:00
Mic
909f8eddb8
Translated using Weblate (Italian)
Currently translated at 100.0% (423 of 423 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-12-08 16:09:54 +01:00
mic
9a0d75c7fc asking openai api optional permission. see #558 2025-12-08 16:08:00 +01:00
mic
e94aeac45b asking claude optional permission. see #558 2025-12-08 16:03:25 +01:00
mic
b7315bf810 version set to 3.7.7 2025-12-08 15:51:53 +01:00
mic
db0c995e3e prepared for release 2025-12-08 15:43:00 +01:00
mic
59d500de43 Rollback #551 2025-12-08 15:40:26 +01:00
mic
d5a790a21b release notes updated 2025-12-08 12:32:27 +01:00
Mic
3c63da4f95 fixed custom div positioning after chatgpt web interface update. see #556 2025-12-08 11:53:11 +01:00
Mic
e580c3efc0
Merge pull request #555 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-12-07 19:00:56 +01:00
Mic
795250212b
Translated using Weblate (French)
Currently translated at 100.0% (422 of 422 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-12-07 18:59:52 +01:00
Mic
0508c9535e
Translated using Weblate (German)
Currently translated at 100.0% (422 of 422 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-12-07 18:59:51 +01:00
Mic
d8dbed9aef
Translated using Weblate (Italian)
Currently translated at 100.0% (422 of 422 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-12-07 18:59:51 +01:00
mic
9fb7a17a15 release notes updated 2025-12-07 18:37:28 +01:00
mic
8d8f8abaf3 added method fixJsonBraces, see #551. 2025-12-07 18:31:07 +01:00
mic
f2dc04b267 Release notes updated 2025-12-07 18:21:52 +01:00
mic
a48d524d6d Using the anthropic system prompt. See #549 2025-12-07 18:20:04 +01:00
mic
f5abf08a9a system_prompt added to the anthropic worker. See #549 2025-12-07 18:09:25 +01:00
mic
ea67c56d22 system_prompt added to the anthropic class. See #549 2025-12-07 18:07:57 +01:00
mic
6211fa5a85 Added anthropic_system_prompt option in the options page. See #549 2025-12-07 18:04:03 +01:00
mic
dc3c75c90e version set to 3.7.6 2025-12-06 12:24:52 +01:00
Mic
1a66591948
Merge pull request #544 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-11-17 22:43:37 +01:00
Ioan Indreias
ea3b8c6a7c
Translated using Weblate (Romanian)
Currently translated at 18.3% (77 of 420 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ro/
2025-11-17 21:43:16 +00:00
Ioan Indreias
ea57d2fd95
Translated using Weblate (Romanian)
Currently translated at 4.5% (19 of 420 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ro/
2025-11-17 21:43:15 +00:00
Ioan Indreias
ee4c1b34d8
Added translation using Weblate (Romanian) 2025-11-17 21:43:15 +00:00
Mic
1146445746
Merge pull request #539 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-11-17 22:43:09 +01:00
Antonio Lucena de Faria
5bdbc5de99
Translated using Weblate (Portuguese)
Currently translated at 13.8% (58 of 420 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt/
2025-10-30 18:05:13 +01:00
mic
34b49c38e8 version set to 3.7.5. release notes updated. 2025-10-22 23:00:29 +02:00
mic
ba12839f1d method name fixed. see #535 2025-10-22 22:58:23 +02:00
mic
0a6931887d version set to 3.7.4. release notes updated. 2025-10-20 18:33:23 +02:00
mic
e51ff2a509 fixing a bug when checking prompt properties. see #534 2025-10-20 18:32:02 +02:00
mic
3f932a602d Anthropic updated to Claude 2025-10-19 23:56:36 +02:00
mic
06a00c4d7a js\lib\diff.js added to VENDORS.md as requested by ATN Reviewers 2025-10-19 23:04:24 +02:00
mic
88c55b2507 diff.js updated with the correct comment header, as requested by ATN reviewers 2025-10-19 23:03:53 +02:00
mic
2d2cba2769 release notes updated 2025-10-16 22:56:43 +02:00
mic
963911b2eb locales updated 2025-10-16 22:53:12 +02:00
mic
30b10dcda0 Asking for the *.openai.com API optional permission. see #529 2025-10-16 22:41:18 +02:00
mic
f2e6412d12 *.openai.com optional permission added. see #529 2025-10-16 22:21:46 +02:00
mic
dda7b785a0 release notes updated 2025-10-16 22:19:20 +02:00
mic
9daa1a76e3 ensuring an empty string when needed. see #520 2025-10-16 22:16:41 +02:00
mic
7b4310ea6b version set to 3.7.3 2025-10-16 22:15:25 +02:00
Mic
7dd26b9b2b
Merge pull request #523 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-10-06 23:53:35 +02:00
Kaloyan Vassilev
85af66f7ca
Translated using Weblate (Bulgarian)
Currently translated at 15.9% (67 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/bg/
2025-10-04 16:02:01 +00:00
mic
fe6c9c55d4 3.7.2 release date fixed 2025-10-03 23:39:47 +02:00
mic
2086fcf1ee release notes updated 2025-10-03 23:36:09 +02:00
mic
8f19cea3cd mztaDoCustomText is now always a string. see #522 2025-10-03 23:33:50 +02:00
Mic
3fccf39852 Merge branch 'main' of github.com:micz/ThunderAI 2025-10-02 20:44:41 +02:00
Mic
a1fbb764ad release notes updated 2025-10-01 23:47:00 +02:00
Mic
4df034a670 chatgpt_isIdle now works also with the thumb-up icon 2025-10-01 23:47:00 +02:00
Mic
1a11238c02 release notes updated 2025-10-01 23:43:00 +02:00
Mic
08d967f9da version set to 3.7.2 2025-10-01 23:43:00 +02:00
Mic
3e8924350e in chatgpt web do not show the force complete hint if the prompt has not been sent 2025-10-01 23:38:00 +02:00
Mic
0e34e9f76d
Merge pull request #519 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-10-01 22:57:33 +02:00
mic
0d33809368 error log changed to warning. see #517 2025-10-01 20:50:43 +02:00
Kaloyan Vassilev
fcca68a56b
Translated using Weblate (Bulgarian)
Currently translated at 15.5% (65 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/bg/
2025-10-01 18:50:41 +00:00
mic
08b66b0495 var assigment fixed 2025-10-01 00:19:04 +02:00
mic
591a556031 typo fixed 2025-09-26 22:09:22 +02:00
Mic
e4fc6d455b
Merge pull request #515 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-09-26 22:05:31 +02:00
mic
a132ab7099 version set to 3.7.1. Release notes updated 2025-09-26 22:05:22 +02:00
mic
a20b06f80f log message fixed 2025-09-26 22:02:36 +02:00
phlostically
4f33422284
Translated using Weblate (Esperanto)
Currently translated at 13.8% (58 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/eo/
2025-09-26 17:45:19 +02:00
mic
684f8eaebb checking response arrays in google gemini worker. see #514 2025-09-24 22:23:39 +02:00
mic
4a61a600d0 prepared for release 2025-09-18 22:04:50 +02:00
Mic
34eeeaddc4
Merge pull request #513 from micz/v3.7.0
v3.7.0
2025-09-18 22:00:59 +02:00
Mic
9dabcf4eb1
Merge branch 'main' into v3.7.0 2025-09-18 22:00:45 +02:00
mic
60ba5e7f67 version set to 3.7.0 2025-09-18 21:59:15 +02:00
Mic
e8c103c82a
Merge pull request #512 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-09-18 21:58:30 +02:00
Mic
c795e9f023
Translated using Weblate (French)
Currently translated at 100.0% (419 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-09-18 10:23:14 +02:00
Mic
7beb4e730f
Deleted translation using Weblate (Dutch (Middle)) 2025-09-18 10:22:48 +02:00
Mic
a2fe88e12a wf renamed 2025-09-17 23:19:52 +02:00
Mic
f87e481b12 added a wf to add a comment on a bug issue without the integration reported 2025-09-17 23:18:23 +02:00
Mic
f5d27a0a70 Anthropic API renamed to Cloude API. see #510 2025-09-16 19:36:00 +02:00
Mic
229809fd1d added a wf to add a comment on a bug issue without the integration reported 2025-09-16 19:36:00 +02:00
Mic
39cb74a3b2 release notes updated 2025-09-16 19:27:00 +02:00
Mic
886ff98abe Anthropic API renamed to Cloude API. see #510 2025-09-16 19:20:00 +02:00
mic
c37b1055e4 vesion set to 3.7.0pre2 2025-09-15 20:34:24 +02:00
Mic
8f6f5e30ad
Update README.md 2025-09-14 23:14:07 +02:00
mic
9d52edbb2c specific prompt integration improved with two new methods: checkAPIIntegration and hasSpecificIntegration. see #438 2025-09-14 23:10:16 +02:00
mic
98a48e1eb1 correctly checking if add tags is active in the menu 2025-09-14 23:02:32 +02:00
mic
bbecf14587 console.log debug line commented out 2025-09-14 23:00:52 +02:00
mic
10d5c4617d info updated 2025-09-14 21:23:18 +02:00
mic
c77696f3fe typo fixed 2025-09-14 21:18:31 +02:00
Mic
cae6cfc8a6
Merge pull request #505 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-09-14 21:13:38 +02:00
Mic
3e87feaa8b
Translated using Weblate (German)
Currently translated at 100.0% (419 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-09-14 21:13:11 +02:00
Mic
65de3a2273
Merge pull request #504 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-09-13 23:30:16 +02:00
Mic
70a369d65b
Translated using Weblate (French)
Currently translated at 100.0% (419 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-09-13 23:29:53 +02:00
Mic
0e9fba03e1
Merge pull request #503 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-09-12 23:53:18 +02:00
Mic
73822b9265
Translated using Weblate (Italian)
Currently translated at 100.0% (419 of 419 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-09-12 23:52:18 +02:00
Gerda Wilhelm
8c55cddbc5
Added translation using Weblate (Dutch (Middle)) 2025-09-12 20:48:16 +00:00
mic
a19d5f7073 added a link to the release page 2025-09-12 22:47:52 +02:00
mic
b92145039f integration order updated 2025-09-12 22:36:17 +02:00
mic
2801d48562 comment body updated 2025-09-12 22:35:04 +02:00
mic
e988bad921 workflow dispatch removed 2025-09-12 22:31:40 +02:00
mic
72efad999b Merge branch 'v3.7.0' of github.com:micz/ThunderAI into v3.7.0 2025-09-12 22:30:44 +02:00
mic
8cf6927282 prerelease workflow ported from main 2025-09-12 22:30:39 +02:00
mic
9895b6f841 prerelease comment on issue workflow added 2025-09-12 22:26:18 +02:00
Mic
78f2936d65 clicking on the force completion message closes it forcing the completion. see #419 2025-09-12 00:17:00 +02:00
mic
9e80391903 version set to 3.7.0pre1 2025-09-11 21:56:20 +02:00
mic
132ece6b0e merge error fixed 2025-09-11 21:51:16 +02:00
Mic
4c944ffdd1
Update README.md 2025-09-10 22:07:05 +02:00
Mic
4ab0f6b9ee release notes updated 2025-09-10 22:00:42 +02:00
Mic
ff6dbb4a55
Merge pull request #497 from micz/issue_438_autofeat_apimodel
Issue 438 autotags and spamfilter can use different API and model
2025-09-10 21:59:22 +02:00
Mic
e5890d487e
Merge branch 'v3.7.0' into issue_438_autofeat_apimodel 2025-09-10 21:58:38 +02:00
Mic
15f6aae91f
Merge branch 'v3.7.0' into issue_438_autofeat_apimodel 2025-09-10 21:57:21 +02:00
Mic
f77d1dabe5 autotag and spamfilter context menu icons added 2025-09-10 00:35:00 +02:00
Mic
edf2de4c34 console.log debug line commented out 2025-09-10 00:35:00 +02:00
Mic
abbc32d7ac popup performance improved 2025-09-10 00:29:00 +02:00
Mic
ca8d6a32d0 console.log debug line commented out 2025-09-10 00:29:00 +02:00
Mic
9087be4811 correctly showing in the popupmenu escaped html characters 2025-09-10 00:22:00 +02:00
Mic
a3bd902b4e rand_call_id numbering fixed 2025-09-09 23:47:00 +02:00
Mic
e3fcaaf248 log statement added 2025-09-09 23:39:00 +02:00
Mic
942a3ba19e log statement added 2025-09-09 23:39:00 +02:00
Mic
a6acc6559c setDefaultPromptsProperties fixed, is no more saving undefined values 2025-09-09 23:36:00 +02:00
Mic
640ff4fa50 getGPTWebModelString improved 2025-09-09 23:36:00 +02:00
Mic
03f2cfafab handling also an undefined value 2025-09-09 23:36:00 +02:00
Mic
f833224b6a missing import added 2025-09-09 23:36:00 +02:00
Mic
f36813f688 release notes updated 2025-09-09 23:14:00 +02:00
mic
48cab1da12 console.log debug statement improved 2025-09-09 22:40:45 +02:00
mic
356885667b context menu loading fixed 2025-09-09 22:27:19 +02:00
mic
0372c8a25d double import removed 2025-09-09 22:18:43 +02:00
mic
9fb1083495 new API calls updated 2025-09-09 22:16:12 +02:00
Mic
fc2d7aa830
Merge pull request #495 from micz/api_improvements
Various API and code improvements
2025-09-09 21:54:49 +02:00
Mic
b7953fe366
Merge branch 'issue_438_autofeat_apimodel' into api_improvements 2025-09-09 21:54:10 +02:00
mic
aad9fcb06d release notes updated 2025-09-09 21:44:03 +02:00
Mic
6f3fdfa2ce two strings added to i18n 2025-09-08 22:15:00 +02:00
Mic
46a8ed4858 css improved 2025-09-08 22:15:00 +02:00
Mic
aeb48c73d1 i18n string fixed 2025-09-08 22:15:00 +02:00
Mic
ac519c3ff5 trim fixed 2025-09-08 22:09:00 +02:00
Mic
7c68561901 gemini thinking budget pref added to the options page. see #494 2025-09-08 22:09:00 +02:00
Mic
59758a76c0 using thinking_budget in gemini. see #494 2025-09-08 22:00:00 +02:00
Mic
2b794690d8 thinkingBudget renamed to thinking_budget. see #494 2025-09-08 22:00:00 +02:00
Mic
9d34ef2cf7 gemini, added model default option for the thinking budget. see #494 2025-09-08 22:00:00 +02:00
Mic
a34d3c41e0 code formatted. better prefs import. 2025-09-08 21:42:00 +02:00
Mic
c02bcc087e info added about gemini thinking budget. see #494 2025-09-08 21:42:00 +02:00
Mic
257236077a prefs loading code improved 2025-09-08 21:42:00 +02:00
Mic
231cc75a2e printing gemini thinking budget on the API webchat. see #494 2025-09-08 21:42:00 +02:00
Mic
9750592ee9 thinkingBudget added to google gemini. see #494 2025-09-08 21:22:00 +02:00
Mic
3c919ac67d APIs constructors are now accepting an object as input argument 2025-09-08 21:13:00 +02:00
Mic
1bc111f96f loading do_debug pref at runtime for auto add tags and spamfilter 2025-09-07 20:10:00 +02:00
Mic
cd07092ac8 spamfilter is now using the prompt api, if present. see #438. 2025-09-07 20:05:00 +02:00
Mic
c55985d076 getConnectionType now has a use_promptspecific_api = true third parameter 2025-09-07 20:05:00 +02:00
Mic
ef57eb6499 translation fixed. see #438 2025-09-07 20:00:00 +02:00
Mic
124b31c830 spamfilter settings page updated. see #438 2025-09-07 20:00:00 +02:00
Mic
6cb2cffd27 console.log debug lines commented out 2025-09-07 20:00:00 +02:00
Mic
8bac021c28 saving and clearing prompt when checking and unchecking the cehckbox for specific api fon addtags. see #438 2025-09-07 19:55:00 +02:00
Mic
b8501f5974 clearPromptAPI method prop names fixed 2025-09-07 19:55:00 +02:00
Mic
d4f7cf5e65 clearPromptAPI method added 2025-09-07 19:55:00 +02:00
Mic
f973f8b8d0 prompt api now used also from the thunderai menu. see #438 2025-09-07 19:50:00 +02:00
mic
119e99df6a thunderai menu addtags is now using the prompt api config. see #438 2025-09-06 00:47:22 +02:00
mic
30c9b3b1ef add_tags_connection_type default value is no more empty. see #438 2025-09-06 00:43:54 +02:00
mic
f8effcc8ce color for dark theme fixed 2025-09-06 00:43:25 +02:00
Mic
fb6815b664 disabling add_tags_use_specific_integration checkbox if chatgptweb is selected. see #438 2025-09-04 23:01:00 +02:00
Mic
3a1e7dde3e correctly hiding connection_ui_end 2025-09-04 23:01:00 +02:00
Mic
1c39801a2a always showing with proper message the addtags and spamfilter rows. see #438 2025-09-04 22:56:00 +02:00
Mic
ee7a033e74 use prompt api and model when assigning tags. see #438 2025-09-04 22:51:00 +02:00
Mic
14b6c97c9d prompt_add_tags_use_list text updated. see #289 2025-09-04 22:46:00 +02:00
Mic
66776d2e20 fixed missing : 2025-09-04 22:46:00 +02:00
Mic
01a1934ddf missing .js in import fixed 2025-09-04 22:46:00 +02:00
Mic
9681a938e3 mzta_specialCommand has now a custom_model parameter. see #438 2025-09-04 22:46:00 +02:00
Mic
9967e28861 mzta_specialCommand is now using an object in input 2025-09-04 22:41:00 +02:00
Mic
72f3c49d77 using prefs_default 2025-09-04 22:41:00 +02:00
Mic
7f9ee613ab code formatted for clarity 2025-09-04 22:41:00 +02:00
Mic
944138a0c2 code reformatting and using prefs_default 2025-09-04 22:36:00 +02:00
Mic
e28f9fed60 using checkSpecificIntegration. see #438 2025-09-04 22:36:00 +02:00
Mic
e7f0eb30d7 checkSpecificIntegration method added 2025-09-04 22:31:00 +02:00
Mic
e2c67a1c5e reloading menus for addtags is now considering addtags_api: prefs_init.add_tags_use_specific_integration. see #438 2025-09-04 22:31:00 +02:00
Mic
005e697e9c getActiveSpecialPromptsIDs is considering addtags specific integration configuration. see #438 2025-09-04 22:26:00 +02:00
Mic
acba02ed44 added info comment 2025-09-04 22:26:00 +02:00
Mic
f1377f7de8 using the prompt conntype in addtags. see #438 2025-09-03 23:18:00 +02:00
Mic
40b6571e04 spamfilter specific model and api default options added. see #438 2025-09-03 23:18:00 +02:00
Mic
c34e5f5fed getConnectionType method added 2025-09-03 23:18:00 +02:00
Mic
72fb7647c3 saving connection type and model per prompt. see #438 2025-09-03 23:13:00 +02:00
Mic
0bd576eb8f allSpecial fixed 2025-09-03 23:13:00 +02:00
Mic
0aa342084c loadPrompt method added to load a single prompt 2025-09-03 23:08:00 +02:00
Mic
e39f48c06c savePrompt method added to save a single prompt 2025-09-03 23:03:00 +02:00
Mic
c6fa1ae54f model prefix added to models id elements. see #438 2025-09-03 22:58:00 +02:00
Mic
9995b78e39 api_type and api_model properties added to prompts. see #438 2025-09-03 22:53:00 +02:00
Mic
572b53df43 correctly switching connectiontype in addtags page. see #438 2025-09-03 22:48:00 +02:00
Mic
bf7fdd3739 tr class added. see #438 2025-09-03 22:43:00 +02:00
Mic
558c96f67c release notes updated 2025-09-03 22:43:00 +02:00
Mic
9b26793895 always trying to remove the add tags menu item before creating it 2025-09-03 22:43:00 +02:00
mic
1cbdd3c485 now adding the release comment automatically 2025-09-03 22:28:40 +02:00
Mic
d8082e22ea options and addtags pages are working. more tests needed and some details on the addtags page need some attention. see #438 2025-09-03 00:54:00 +02:00
Mic
c8d0d430d3 work in progress, moved html to connection-ui.js, starting to move the relative methods. see #438 2025-09-02 22:55:00 +02:00
Mic
ef78043bb9 using isAPIKeyValue method 2025-09-02 22:50:00 +02:00
Mic
c15fe8e85f isAPIKeyValue method added 2025-09-02 22:50:00 +02:00
Mic
0ec19550c0 moved populateConnectionTypeOptions 2025-09-02 22:50:00 +02:00
Mic
e551974a56 work in progress, saving a point before working on generalizing the connetiontype html code. see #438 2025-09-02 22:45:00 +02:00
Mic
d404897911 connection_type dynamic loading 2025-09-02 22:45:00 +02:00
Mic
76f743e88f
Merge pull request #492 from micz/issue_289_autotag_list
Issue 289 Autotag list
2025-09-02 21:02:09 +02:00
mic
d46645a2fa passing prefs when preparing the prompt. see #289 2025-09-02 21:00:59 +02:00
mic
9e987e4e30 var name fixed 2025-09-02 20:53:30 +02:00
mic
593a0d5db0 autotag list option saved in the correct format. see #289 2025-09-02 20:51:43 +02:00
mic
6b0543b154 text improved. see #289 2025-09-02 20:48:01 +02:00
Mic
64b8b82633 label improved 2025-09-02 20:31:34 +02:00
Mic
0f22ae5148 adding the statement to the prompt to limit the used tags. see #289 2025-09-01 23:45:00 +02:00
Mic
c25639b245 normalizeStringList method improved again 2025-09-01 23:40:00 +02:00
Mic
b8cb3adfc6 filtering tags in autotagging. see #289 2025-09-01 23:40:00 +02:00
Mic
f3050d5277 normalising tag list. see #289 2025-09-01 23:35:00 +02:00
Mic
e563492e3f normalizeStringList method improved 2025-09-01 23:30:00 +02:00
Mic
34fcb3c157 normalizeStringList method added 2025-09-01 23:30:00 +02:00
Mic
3da11ef612 in the add tags page now is possibile to manage the auto add tags list. see #289 2025-09-01 23:25:00 +02:00
Mic
96aa66aa53 Merge branch 'main' of github.com:micz/ThunderAI 2025-09-01 22:28:01 +02:00
Mic
a981654ec8 Add workflow to automatically label closed issues as "released" when needed 2025-09-01 22:27:51 +02:00
Mic
7593ff0729 release notes updated 2025-08-31 15:51:00 +02:00
Mic
9c0583af51 Show the prompt id and name to the information in the AI API chat. See #436 2025-08-31 15:51:00 +02:00
Mic
bd2762b9d6 release notes updated 2025-08-31 15:46:00 +02:00
Mic
0f3495043c Added a message to explain to click on force completion after 7 seconds. see #419 2025-08-31 15:46:00 +02:00
Mic
4be5db1373 Improved getAPIsInitMessageString args handling. see #491 2025-08-31 15:41:00 +02:00
mic
95591993b8 console.log debug statement removed 2025-08-29 21:01:36 +02:00
mic
399664cc04 missing space 2025-08-29 21:00:39 +02:00
Mic
bd9ee2392a
Merge pull request #489 from micz/issue471
Improved prompts method args handling. see #471
2025-08-29 20:59:49 +02:00
mic
315f3e1c3e zh_Hant updated 2025-08-29 20:54:03 +02:00
Mic
fc1802a76f
Merge pull request #487 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-29 20:52:21 +02:00
Evereasy
2d7d68dcab
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (405 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2025-08-29 17:38:33 +02:00
Mic
5af9a82951 Improved prompts method args handling. see #471 2025-08-28 21:09:00 +02:00
Mic
87303adfb1 release notes updated 2025-08-28 20:54:00 +02:00
Mic
f82aa23560 mail_attachments_info placeholder added. see #446 2025-08-28 20:54:00 +02:00
Mic
9292b0d02e Deepseek added to the openai compatible api presets. see #486 2025-08-28 20:49:00 +02:00
Mic
5d75226f40 implemented the new api call, no response elaboration yet 2025-08-28 20:44:00 +02:00
Mic
53fc7eecdd version set to 3.7.0 2025-08-28 20:44:00 +02:00
Mic
68a14ff4ba
Update README.md 2025-08-28 07:43:44 +02:00
mic
9c5b29ed89 prepared for release 2025-08-23 23:42:16 +02:00
Mic
d39d20adb7
Merge pull request #483 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-23 23:40:53 +02:00
Mic
d2919e277a
Translated using Weblate (Polish)
Currently translated at 70.3% (285 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pl/
2025-08-23 23:40:01 +02:00
Benedek Vigh (冯白诺)
a4a4010ace
Translated using Weblate (Hungarian)
Currently translated at 1.2% (5 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hu/
2025-08-22 23:36:41 +02:00
Benedek Vigh (冯白诺)
c42b7e7225
Added translation using Weblate (Hungarian) 2025-08-22 23:36:40 +02:00
mic
2a1e5489d7 release notes updated 2025-08-22 23:35:07 +02:00
mic
57e9a05083 fix correctly showing the context menu when changing connection type 2025-08-22 23:33:53 +02:00
mic
b6a70b11f9 release notes updated 2025-08-22 23:26:33 +02:00
mic
49b9ab1b6c improved linebreaks. see #482 2025-08-22 23:24:16 +02:00
mic
74f5369a31 converting lines breaks to paragraphs in chatgpt web interface integration prompt. see #482 2025-08-22 23:22:21 +02:00
mic
ad6ac50dc9 method convertNewlinesToParagraphs added. see #482 2025-08-22 23:16:57 +02:00
mic
86a457c01c converting newlines to <br> when sending the prompt to the api chat, to preserve the breaklines in the chat. To the AI is sent without <br>. see #469 2025-08-22 23:02:26 +02:00
Mic
ebf9b1a31c
Merge pull request #481 from micz/3.6.1_issue_469
3.6.1 issue 469
2025-08-22 22:49:59 +02:00
Mic
c17b3187b2
Merge branch 'main' into 3.6.1_issue_469 2025-08-22 22:49:47 +02:00
Mic
f3e0d5401e
Merge pull request #478 from kiliansinger/3.6.1_issue_469
3.6.1 issue 469
2025-08-22 22:48:35 +02:00
Kilian Singer
c90f9c1b9b added cleanup of newlines also to only_quoted_text 2025-08-22 17:30:41 +02:00
Mic
268140bd04
Merge pull request #480 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-22 11:48:52 +02:00
Konstantin Spirin
2b9012556c
Translated using Weblate (Russian)
Currently translated at 100.0% (405 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-08-22 11:48:16 +02:00
Mic
c5e43b690c
Merge pull request #479 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-22 11:39:29 +02:00
G S (TAra)
684fa2e795
Translated using Weblate (Russian)
Currently translated at 100.0% (405 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-08-22 11:38:54 +02:00
Kilian Singer
645d0845a1 removed debugging string 2025-08-21 09:49:28 +02:00
Kilian Singer
51614ea95d new lines are now preserved in mzta-menus.js
also newlines are normalized to \n in chase
\r\n (like on windows platforms) are present.
some LLMs work better with proper paragraph breaks.
2025-08-21 09:37:43 +02:00
Mic
3238f1ce6e
Merge pull request #477 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-20 22:12:00 +02:00
Mic
c23248a9c3
Translated using Weblate (French)
Currently translated at 100.0% (405 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-08-20 22:11:43 +02:00
Mic
73183ff8f5
Translated using Weblate (Italian)
Currently translated at 100.0% (405 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-08-20 22:11:43 +02:00
Mic
5e46773a76
Translated using Weblate (German)
Currently translated at 100.0% (405 of 405 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-08-20 22:11:42 +02:00
mic
9f5a069588 updated release notes 2025-08-20 22:06:23 +02:00
mic
d68e7d6d68 in the openai comp integration is now possibile to clear the models list. see #472 2025-08-20 22:05:13 +02:00
Mic
eb3416db59
Merge pull request #476 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-20 21:57:05 +02:00
Mic
8574a57666
Translated using Weblate (French)
Currently translated at 100.0% (403 of 403 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-08-20 21:56:15 +02:00
Mic
e065b90556
Translated using Weblate (Italian)
Currently translated at 100.0% (403 of 403 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-08-20 21:56:14 +02:00
Mic
52b8a840e7
Translated using Weblate (German)
Currently translated at 100.0% (403 of 403 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-08-20 21:56:14 +02:00
mic
704fa10a04 chatgpt web models list fixed. see #464 2025-08-20 21:53:16 +02:00
mic
9d96e6bc3f release notes updated 2025-08-20 21:43:30 +02:00
mic
7fbe0c0338 forcing exixting tags also when using the ThuderAI menu. see #475 2025-08-20 21:41:35 +02:00
mic
6269acb5ec release notes updated 2025-08-20 21:27:07 +02:00
mic
3851c10bcc remove commented-out code for HTML to plain text conversion in processEmails function 2025-08-20 21:16:35 +02:00
mic
7a1d14793e version set again to 3.6.1 2025-08-20 21:14:57 +02:00
Mic
9ac4675345
Merge pull request #474 from micz/3.6.1_issue_469
3.6.1 issue #469
2025-08-20 21:13:28 +02:00
Mic
1fd08225f8
Merge pull request #473 from kiliansinger/3.6.1_issue_469
used DOMParser to convert HTML to plain text
2025-08-20 21:12:44 +02:00
Kilian Singer
09d620c294 also removing <style> tags 2025-08-20 18:42:36 +02:00
Kilian Singer
c24097245b added export keyword 2025-08-20 18:21:04 +02:00
Kilian Singer
a96702b0a8 used DOMParser to convert HTML to plain text 2025-08-20 18:10:18 +02:00
mic
2fa356ee6d trying a new way to get the plain text email in auto fetaures. see #469 2025-08-20 15:49:06 +02:00
mic
9facfc5f51 version set to 3.6.1_issue_469 2025-08-20 15:48:42 +02:00
mic
9483a57936 Enhance htmlBodyToPlainText function to handle additional block tags and improve HTML tag removal 2025-08-20 09:46:49 +02:00
mic
14da34c44e release notes updated 2025-08-19 16:31:50 +02:00
mic
cc711e55ba Add htmlBodyToPlainText fallback for empty message bodies. see #470 2025-08-19 16:25:14 +02:00
mic
8223f4ef4f Add htmlBodyToPlainText function to sanitize HTML content. see #470 2025-08-19 16:24:17 +02:00
mic
8878612f20 release notes updated 2025-08-11 22:28:32 +02:00
mic
58d449c7e6 chatgpt web interface models list updated. see #464 2025-08-11 22:27:41 +02:00
Mic
65665aa5a2
Merge pull request #467 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-11 22:20:48 +02:00
Mic
c4190a6c00
Translated using Weblate (French)
Currently translated at 100.0% (403 of 403 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-08-11 22:16:16 +02:00
Mic
a3dbcb9042
Translated using Weblate (Italian)
Currently translated at 100.0% (403 of 403 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-08-11 22:16:15 +02:00
Mic
e72a524830
Translated using Weblate (German)
Currently translated at 100.0% (403 of 403 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-08-11 22:16:15 +02:00
mic
99ad461c84 added info about br replaceing in chatgpt web interface. see #462 2025-08-11 22:11:20 +02:00
mic
43ca26da6a release notes updated 2025-08-11 22:06:58 +02:00
mic
f97acf0ece chatgpt web interface is now stripping any <br> tag in the response. see #462 2025-08-11 22:04:26 +02:00
mic
dda315be57 release notes updated 2025-08-11 22:00:16 +02:00
mic
98352938af perplexity ai config fixed. see #461 2025-08-11 21:59:07 +02:00
Mic
f8b8a9287c
Merge pull request #466 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-11 21:48:07 +02:00
Bogomil Shopov
1299623f0a
Translated using Weblate (Bulgarian)
Currently translated at 2.7% (11 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/bg/
2025-08-11 21:45:46 +02:00
Mic
c67b900c84
Translated using Weblate (French)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-08-11 21:45:46 +02:00
Andrés Rendón Hernández
be14ea4855
Translated using Weblate (Spanish)
Currently translated at 12.1% (49 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/es/
2025-08-09 22:02:00 +02:00
Mic
50cca79e08
Merge pull request #463 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-08-07 23:15:56 +02:00
mic
cd962dcf06 version set to 3.6.1 2025-08-07 23:15:10 +02:00
Bogomil Shopov
dbe47243eb
Translated using Weblate (Bulgarian)
Currently translated at 2.4% (10 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/bg/
2025-08-07 17:17:56 +02:00
Evereasy
665caa2888
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2025-08-07 17:17:56 +02:00
Bogomil Shopov
2d5531a162
Added translation using Weblate (Bulgarian) 2025-08-07 11:45:57 +02:00
mic
da7c288ff6 no more using innerHTML. fixes #457 2025-08-02 00:30:06 +02:00
mic
26dbae954e VENDORS.md file added. fixes #458 2025-08-02 00:24:59 +02:00
mic
a96924d3d7 missing feature added to CHANGELOG.md 2025-08-01 23:27:17 +02:00
mic
bc9c4e2669 update release date for version 3.5.5. 2025-08-01 23:26:39 +02:00
Mic
edf4b7dc39
Merge pull request #456 from micz/v3.6.0
v3.6.0
2025-07-30 22:40:38 +02:00
Mic
a66ebee014
Merge branch 'main' into v3.6.0 2025-07-30 22:40:00 +02:00
mic
116c0ce78c version prepared for release 2025-07-30 22:36:09 +02:00
Mic
5b42e960a6
Merge pull request #455 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-07-30 22:32:56 +02:00
Mic
be344cc6d7
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 99.5% (400 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2025-07-30 22:32:36 +02:00
Mic
1a396a12d1
Translated using Weblate (Russian)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-30 22:32:36 +02:00
Mic
ddb9fb41c1
Translated using Weblate (French)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-07-30 22:32:36 +02:00
Mic
1ac02d515c
Translated using Weblate (Italian)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-07-30 22:32:35 +02:00
Mic
846303f8e3
Translated using Weblate (Croatian)
Currently translated at 69.1% (278 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/hr/
2025-07-30 22:32:35 +02:00
Mic
bc1ba4e889
Translated using Weblate (German)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-07-30 22:32:35 +02:00
Mic
b9322562dd
Translated using Weblate (Portuguese (Brazil))
Currently translated at 68.4% (275 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt_BR/
2025-07-30 22:32:35 +02:00
mic
02deccca61 add tags special prompts quotes fixed 2025-07-30 22:27:09 +02:00
Mic
312bce521e
Merge pull request #453 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-07-28 21:16:35 +02:00
Maksim_220 Кабанов
fe3f0a1e53
Translated using Weblate (Russian)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-28 21:15:30 +02:00
Mic
0f01ce4bdd
Translated using Weblate (French)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-07-28 21:15:30 +02:00
Mic
0d2c635455
Translated using Weblate (Italian)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-07-28 21:15:30 +02:00
Mic
3d25cfd11f
Translated using Weblate (German)
Currently translated at 100.0% (402 of 402 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-07-28 21:15:29 +02:00
mic
032bd37cb4 autoscroll to bottom fixed in chatgpt web interface integration 2025-07-25 23:27:04 +02:00
mic
b63dfdc247 release notes updated 2025-07-25 23:17:13 +02:00
mic
51068dd95c Added a new default prompt to reply with a custom command asked when exectutin the prompt. See #444 2025-07-25 23:15:30 +02:00
mic
3a2845a23c 3.5.5 fixes ported to 3.6.0. Fixes #450 2025-07-25 22:57:53 +02:00
Mic
16b47a066c antispam optional permissions fixed 2025-07-21 23:49:06 +02:00
Mic
42ef8eeb35 version set to 3.5.5 and realese noted updated 2025-07-21 23:43:49 +02:00
Mic
4507847105 working on #449 2025-07-21 23:43:33 +02:00
Mic
dd021476bf
Merge pull request #448 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-07-17 23:12:45 +02:00
Evereasy
1998557740
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2025-07-12 19:38:01 +02:00
Evereasy
b3550ae410
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2025-07-12 19:38:01 +02:00
Mic
cd94403292
Merge pull request #445 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-07-06 22:23:15 +02:00
Afonso Nóbrega
3765159599
Translated using Weblate (Portuguese)
Currently translated at 13.0% (52 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt/
2025-07-06 22:22:44 +02:00
mic
f1ec46c408 Add Russian translation and update release notes 2025-07-05 21:12:12 +02:00
Mic
2ff92276c3
Merge pull request #443 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-07-05 21:06:32 +02:00
Maksim_220 Кабанов
753f7c445f
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:36 +02:00
Maksim_220 Кабанов
8e22de921e
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:36 +02:00
Maksim_220 Кабанов
06c61d549c
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:36 +02:00
Maksim_220 Кабанов
8f8d36cf62
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:35 +02:00
Maksim_220 Кабанов
6bb4fe79b1
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:35 +02:00
Maksim_220 Кабанов
7cbbaa0ddb
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:35 +02:00
Maksim_220 Кабанов
5e644536d6
Translated using Weblate (Russian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/ru/
2025-07-05 03:04:35 +02:00
MIRT M
770a0509fb
Added translation using Weblate (Slovak) 2025-07-02 13:49:25 +02:00
Mic
d2f7bfa699
Merge pull request #440 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-06-28 14:49:44 +02:00
Mic
6d86fd28ee
Translated using Weblate (French)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-06-28 14:49:08 +02:00
Mic
0bfbd5b903
Translated using Weblate (French)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-06-28 14:49:08 +02:00
Mic
604cedf64d
Translated using Weblate (German)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-06-28 14:49:08 +02:00
Mic
84730b6615
Translated using Weblate (German)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-06-28 14:49:08 +02:00
Mic
5a0f6bc0d9
Translated using Weblate (German)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-06-28 14:49:07 +02:00
Mic
b8fbc9af54
Translated using Weblate (German)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-06-28 14:49:07 +02:00
Afonso Nóbrega
ed65d19dec
Translated using Weblate (Portuguese)
Currently translated at 10.5% (42 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/pt/
2025-06-24 19:02:00 +02:00
Afonso Nóbrega
b766a3b389
Added translation using Weblate (Portuguese) 2025-06-23 18:04:55 +02:00
Mic
66a64f924b fix: reply type button enable/disable only when present 2025-06-20 22:17:41 +02:00
Mic
b0135bcdf3 change reply type button improved in hatgpt web interface. see #372 2025-06-19 23:50:00 +02:00
Mic
9ac4445f58
Merge pull request #437 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-06-19 23:45:54 +02:00
Mic
8a63cf2334
Translated using Weblate (Italian)
Currently translated at 100.0% (400 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-06-19 23:44:47 +02:00
Mic
39e3c3adb8
Translated using Weblate (Italian)
Currently translated at 95.7% (383 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-06-19 23:39:03 +02:00
mic
311f06069b Update exclusion list description for clarity 2025-06-19 23:38:53 +02:00
mic
1dac21f99f version set to 3.6.0pre3 2025-06-19 22:36:46 +02:00
mic
9d06f6c868 log statements added 2025-06-19 22:35:28 +02:00
Mic
506abe7a07
Merge pull request #434 from weblate/weblate-thunderai-main
Translations update from Hosted Weblate
2025-06-19 21:46:24 +02:00
Mic
60dd39a75f
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 95.7% (383 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/zh_Hant/
2025-06-19 21:42:07 +02:00
Mic
09342f79da
Translated using Weblate (Czech)
Currently translated at 93.2% (373 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/cs/
2025-06-19 21:42:06 +02:00
Mic
274d861cee
Translated using Weblate (French)
Currently translated at 93.2% (373 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/fr/
2025-06-19 21:42:06 +02:00
Mic
f521463631
Translated using Weblate (Italian)
Currently translated at 95.2% (381 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-06-19 21:42:06 +02:00
Mic
ecb47732a5
Translated using Weblate (German)
Currently translated at 93.2% (373 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/de/
2025-06-19 21:42:06 +02:00
Mic
b2cad4b635
Translated using Weblate (Italian)
Currently translated at 95.2% (381 of 400 strings)

Translation: ThunderAI for Thunderbird/main
Translate-URL: https://hosted.weblate.org/projects/thunderai/main/it/
2025-06-19 21:36:43 +02:00
Mic
647f23a50b Improved the AI web chat init message 2025-06-19 21:36:28 +02:00
Mic
8608501da0 send button shadow fixed. see #435 2025-06-19 21:15:10 +02:00
Mic
d4d1653ac7 Enhance word diff rendering by splitting segments on <br> tags and appending appropriate span elements for added, removed, and unchanged text. 2025-06-19 00:33:00 +02:00
Mic
abfd8268cb Enhance HTML rendering in the diffViewer by splitting content on <br> tags and creating span elements for added, removed, and unchanged text. 2025-06-19 00:28:00 +02:00
mic
4b61e06837 version set to 3.6.0pre2 2025-06-18 23:24:29 +02:00
mic
487812dd38 release notes updated 2025-06-18 23:24:03 +02:00
Mic
c524f8c87c
Merge pull request #433 from micz/new_html_parsing
New html parsing
2025-06-18 23:22:47 +02:00
Mic
f8b7f2fbf5
Update bug_report.yml 2025-06-15 23:39:08 +02:00
mic
cc2dd556c0 Recreate feature request template with detailed fields for user input 2025-06-15 23:35:43 +02:00
mic
21b2a48f8c Add Google Gemini API and Anthropic API options to bug report template 2025-06-15 23:35:12 +02:00
Mic
58689fb05a
Update feature_request.md 2025-06-15 23:28:37 +02:00
Mic
c1c1e77aa9 release notes updated 2025-06-12 23:35:00 +02:00
Mic
ec4bd3c366 scroll to bottom fixed in chatgpt web interface 2025-06-12 23:35:00 +02:00
Mic
3e09d1be61 version set to 3.5.4 and release notes updated 2025-06-12 23:15:00 +02:00
Mic
42ed50151d Refactor icon selection logic for regenerate and read aloud buttons. again 2025-06-12 23:15:00 +02:00
mic
e45617d819 version set to 3.5.3 and release notes updated 2025-06-10 23:42:23 +02:00
mic
ad5afee395 Enhance icon detection logic for regenerate and read aloud buttons 2025-06-10 23:42:11 +02:00
179 changed files with 30433 additions and 3545 deletions

View file

@ -8,7 +8,7 @@ body:
If you have a feature or enhancement request, please use the [feature request][fr] form.
[fr]: https://github.com/micz/ThunderAI/issues/new?assignees=&labels=&projects=&template=feature_request.md&title=
[fr]: https://github.com/micz/ThunderAI/issues/new?assignees=&labels=&projects=&template=feature_request.yml&title=
- type: textarea
validations:
required: true
@ -36,7 +36,7 @@ body:
attributes:
label: Which version of Thunderbird are you using?
description: >
Thunderbird version like 115.14.0 or 128.1.
Thunderbird version like 140.0 or 147.0.1.
- type: input
id: version
validations:
@ -52,8 +52,11 @@ body:
attributes:
label: Which integration are you using?
options:
- -- Select an option --
- ChatGPT Web Interface
- OpenAI ChatGPT API
- Google Gemini API
- Claude API
- Ollama API
- OpenAI Compatible API
- type: markdown

View file

@ -1,21 +0,0 @@
---
name: Feature Request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe it clearly.**\
Provide a clear and concise explanation of the problem you're experiencing or the limitation you're facing.\
_Example: "I'm often frustrated when I can't filter results by date..."_
**Describe the feature you'd like to see implemented.**\
What should happen? Describe the ideal solution or behavior in detail. Be as specific as possible.
**Why is this feature valuable?**\
Explain how this feature would improve the project or user experience. Who benefits from it, and why?
**Additional context, mockups, or screenshots**\
Feel free to include anything else that can help understand the feature request better, like images, sketches, links, references, etc.

View file

@ -0,0 +1,40 @@
name: Feature Request
description: Suggest a new idea for ThunderAI
body:
- type: markdown
attributes:
value: |
This issue form is for suggesting new ideas only!
If you need to report a bug, please use the [bug][bg] form.
[bg]: https://github.com/micz/ThunderAI/issues/new?template=bug_report.yml
- type: textarea
validations:
required: true
id: idea
attributes:
label: Your idea
description: >-
Describe the idea you'd like to see implemented in ThunderAI.
Provide a clear and concise description.
- type: markdown
attributes:
value: |
# Details
- type: textarea
id: value
attributes:
label: Value
description: >-
What value does this idea bring to ThunderAI? How does it improve the
user experience or functionality?
- type: textarea
id: additional
attributes:
label: Additional information
description: >
If you have any additional information, use the field below.
Please note, you can attach screenshots or screen recordings here, by
dragging and dropping files in the field below.

80
.github/scripts/tom-select-update.js vendored Normal file
View file

@ -0,0 +1,80 @@
const fs = require('fs');
const https = require('https');
const path = require('path');
// --- Utility: fetch URL following redirects ---
function fetchUrl(url) {
return new Promise((resolve, reject) => {
https.get(url, { headers: { 'User-Agent': 'ThunderAI-vendor-updater' } }, (res) => {
if (res.statusCode === 301 || res.statusCode === 302) {
return fetchUrl(res.headers.location).then(resolve).catch(reject);
}
const chunks = [];
res.on('data', chunk => chunks.push(chunk));
res.on('end', () => resolve({ status: res.statusCode, body: Buffer.concat(chunks) }));
}).on('error', reject);
});
}
// --- Read VENDORS.md ---
const vendorsPath = 'VENDORS.md';
const content = fs.readFileSync(vendorsPath, 'utf8');
// --- Find all entries: file + source ---
const entryRegex = /file:\s*(.+?)\r?\nsource:\s*(https?:\/\/.+)/g;
const entries = [];
let match;
while ((match = entryRegex.exec(content)) !== null) {
entries.push({
file: match[1].trim(),
source: match[2].trim(),
});
}
// --- Filter tom-select entries only ---
const filteredEntries = entries.filter(e => e.file.toLowerCase().includes('tom-select'));
if (filteredEntries.length === 0) {
console.log('No entries found in VENDORS.md');
process.exit(0);
}
// --- Main ---
(async () => {
let hasErrors = false;
for (const entry of filteredEntries) {
const filePath = entry.file.replace(/\\/g, '/');
console.log(`\nProcessing: ${filePath}`);
console.log(` Source: ${entry.source}`);
// Create directory if it doesn't exist
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log(` → Directory created: ${dir}`);
}
// Download file
try {
const res = await fetchUrl(entry.source);
if (res.status === 200) {
fs.writeFileSync(filePath, res.body);
console.log(` ✓ File updated (${res.body.length} bytes)`);
} else {
console.error(` ✗ Download failed: HTTP ${res.status}`);
hasErrors = true;
}
} catch (err) {
console.error(` ✗ Error: ${err.message}`);
hasErrors = true;
}
}
if (hasErrors) {
console.error('\nSome files were not updated.');
process.exit(1);
} else {
console.log('\nAll files updated successfully.');
}
})();

117
.github/workflows/auto-mark-released.yml vendored Normal file
View file

@ -0,0 +1,117 @@
name: Mark released issues on close
on:
issues:
types: [closed]
permissions:
contents: read
issues: write
jobs:
mark-released:
# Run only if closed as completed AND has at least one "status:" label
if: ${{ github.event.issue.state_reason == 'completed' && contains(toJSON(github.event.issue.labels), 'status:') }}
runs-on: ubuntu-latest
steps:
- name: Set "released" label when closed completed and was ready for release
uses: actions/github-script@v7
with:
script: |
// Helpers
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue = context.payload.issue;
if (!issue) {
core.info('No issue payload found, skipping.');
return;
}
// Only proceed if closed as "completed" (not "not_planned")
const isCompleted = issue.state_reason === 'completed';
if (!isCompleted) {
core.info('Issue state_reason is not "completed"; skipping.');
return;
}
const getName = (l) => typeof l === 'string' ? l : l.name;
const labels = (issue.labels || []).map(getName);
// Status detection (robust to case/spacing)
const isStatusLabel = (name) => /^status:\s*/i.test(String(name || ''));
const hasAnyStatus = labels.some(isStatusLabel);
if (!hasAnyStatus) {
core.info('Issue has no "status:*" label; skipping.');
return;
}
const READY_REGEX = /^status:\s*ready\s*for\s*release$/i;
const hasReady = labels.some((n) => READY_REGEX.test(String(n || '')));
if (!hasReady) {
core.info('Issue is not "status: ready for release"; nothing to do.');
return;
}
const releasedLabel = 'status: released';
// Ensure "released" label exists
try {
await github.rest.issues.getLabel({ owner, repo, name: releasedLabel });
} catch (e) {
if (e.status === 404) {
core.info(`Label "${releasedLabel}" not found. Creating it.`);
await github.rest.issues.createLabel({
owner,
repo,
name: releasedLabel,
color: '184738', // deep green
description: 'Feature released.'
});
} else {
throw e;
}
}
// Remove all status:* labels, add "status: released"
const filtered = labels.filter((name) => !isStatusLabel(name));
const newLabels = [...new Set([...filtered, releasedLabel])];
await github.rest.issues.update({
owner,
repo,
issue_number: issue.number,
labels: newLabels
});
core.info(`Issue #${issue.number} relabeled as "${releasedLabel}".`);
// === NEW: add release comment with milestone if present ===
const milestone = issue.milestone;
if (!milestone || !milestone.title) {
core.info('Issue has no milestone; no release comment added.');
return;
}
const commentBody = `Released in version ${milestone.title}.`;
// Avoid duplicate comment if the action reruns
const existingComments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: issue.number, per_page: 100 }
);
const alreadyCommented = existingComments.some(c =>
typeof c.body === 'string' && c.body.trim() === commentBody
);
if (alreadyCommented) {
core.info('Release comment already present; skipping comment creation.');
} else {
await github.rest.issues.createComment({
owner,
repo,
issue_number: issue.number,
body: commentBody
});
core.info('Release comment added.');
}

View file

@ -0,0 +1,75 @@
name: Issues Validate Integration Field
on:
issues:
types: [opened, edited]
permissions:
issues: write
jobs:
check-integration:
runs-on: ubuntu-latest
steps:
- name: Validate dropdown selection (only for bug report form)
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const bodyText = issue.body || "";
// ---- Guard: only act if this looks like a Bug Report form ----
if (!bodyText.includes("### The problem")) {
core.info("Skipped: This issue does not contain '### The problem', so it is not a Bug Report.");
return;
}
core.info("Detected a Bug Report issue. Proceeding with validation...");
// Extract selection under "Which integration are you using?"
const header = "### Which integration are you using?";
const nextHeaderRegex = /\n### /;
let selection = "";
const startIdx = bodyText.indexOf(header);
if (startIdx !== -1) {
const afterHeader = bodyText.slice(startIdx + header.length).replace(/^\r?\n+/, "");
const nextHeaderIdx = afterHeader.search(nextHeaderRegex);
selection = (nextHeaderIdx === -1 ? afterHeader : afterHeader.slice(0, nextHeaderIdx)).trim();
}
core.info(`Integration field extracted: "${selection}"`);
const isInvalid = !selection || selection.startsWith("-- Select an option");
if (isInvalid) {
core.info("Integration field is invalid or not selected.");
} else {
core.info("Integration field is valid. Nothing to do.");
}
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = issue.number;
// Avoid duplicate comments
const marker = "please specify **Which integration are you using?**";
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number });
const alreadyCommented = comments.some(c => c.body && c.body.includes(marker));
if (isInvalid) {
if (!alreadyCommented) {
core.info("No existing reminder found. Posting a new comment...");
await github.rest.issues.createComment({
owner, repo, issue_number,
body: [
`👋 Hello @${issue.user.login}!`,
`To complete your bug report, please specify which integration you are using.`,
"",
"Right now the field `**Which integration are you using?**` is set to `-- Select an option --`.",
"",
"Click **Edit** at the top right of the issue, choose a valid option from the dropdown, and save.",
].join("\n")
});
} else {
core.info("Reminder comment already exists. Skipping new comment.");
}
}

View file

@ -0,0 +1,103 @@
name: pre-release comment issues
on:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
permissions:
contents: read
issues: write
jobs:
comment-milestone-issues:
# allow manual run for testing; in production, only prerelease
if: ${{ github.event.release.prerelease == true }}
runs-on: ubuntu-latest
steps:
- name: Debug context (no checkout)
run: |
echo "Event: ${{ github.event_name }}"
echo "Default branch: ${{ github.event.repository.default_branch }}"
echo "Release tag: ${{ github.event.release.tag_name || 'N/A' }}"
echo "This workflow file lives on MAIN and is executed as-is (no checkout)."
- name: Add comment to issues of matching milestone (filtered by labels)
uses: actions/github-script@v7
with:
script: |
// core, github, context are already available in github-script
await (async () => {
const parsePrereleaseTag = (tag) => {
const m = /^v?(\d+\.\d+\.\d+)pre(\d+)$/.exec(tag ?? "");
return m ? { milestoneTitle: m[1], preNumber: Number(m[2]) } : null;
};
const { owner, repo } = context.repo;
// If this is a manual run, exit with a clear message
if (context.eventName !== 'release') {
core.notice("Manual run: no release payload, nothing to do.");
return;
}
const tagName = context.payload.release?.tag_name;
if (!tagName) { core.notice("No tag_name found on release event."); return; }
const parsed = parsePrereleaseTag(tagName);
if (!parsed) { core.notice(`Tag '${tagName}' does not match vX.Y.ZpreN. Skipping.`); return; }
const milestoneTitle = parsed.milestoneTitle; // es. "3.7.0"
const prereleaseTagDisplay = tagName.startsWith("v") ? tagName : `v${tagName}`;
const commentBody = `This feature is available for testing in the pre-release version [${prereleaseTagDisplay}](https://github.com/micz/ThunderAI/releases).`;
core.info(`(MAIN) Looking for milestone '${milestoneTitle}' in ${owner}/${repo}`);
// Find milestone (open or closed)
const milestones = await github.paginate(
github.rest.issues.listMilestones,
{ owner, repo, state: "all", per_page: 100 }
);
const milestone = milestones.find(m => m.title === milestoneTitle);
if (!milestone) { core.warning(`Milestone '${milestoneTitle}' not found.`); return; }
// All issues in the milestone
const issues = await github.paginate(
github.rest.issues.listForRepo,
{ owner, repo, milestone: milestone.number, state: "all", per_page: 100 }
);
// Only issues (no PRs) with the requested labels
const allowed = new Set(["status: in review", "status: ready for release"]);
const targets = issues.filter(i =>
!i.pull_request &&
Array.isArray(i.labels) &&
i.labels.some(l => allowed.has(l.name))
);
core.info(`Candidate issues: ${targets.length}`);
let commented = 0;
for (const issue of targets) {
const comments = await github.paginate(
github.rest.issues.listComments,
{ owner, repo, issue_number: issue.number, per_page: 100 }
);
const exists = comments.some(c => (c.body || "").trim() === commentBody);
if (exists) {
core.info(`#${issue.number}: comment already present, skip.`);
continue;
}
await github.rest.issues.createComment({
owner, repo, issue_number: issue.number, body: commentBody
});
commented++;
core.info(`#${issue.number}: comment added.`);
}
core.info(`Done. Added comment to ${commented} issue(s).`);
})();

View file

@ -0,0 +1,61 @@
name: Check Tom-Select Latest Release
on:
schedule:
- cron: '0 19 * * *' # Check every day at 19:00
workflow_dispatch: # Allows manual triggering for testing purposes
permissions:
contents: read
issues: write
jobs:
check-and-notify:
runs-on: ubuntu-latest
steps:
- name: Get latest release from external repo
id: get_release
run: |
REPO_TARGET="orchidjs/tom-select"
LATEST_TAG=$(curl -s https://api.github.com/repos/$REPO_TARGET/releases/latest | jq -r .tag_name)
if [ "$LATEST_TAG" == "null" ] || [ -z "$LATEST_TAG" ]; then
echo "Error: unable to fetch tag or no release found."
exit 1
fi
echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "target=$REPO_TARGET" >> $GITHUB_OUTPUT
- name: Check if Issue already exists and create it
uses: actions/github-script@v7
with:
script: |
const latestTag = "${{ steps.get_release.outputs.tag }}";
const targetRepo = "${{ steps.get_release.outputs.target }}";
const { owner, repo } = context.repo;
const issueTitle = `Update Tom Select to version ${latestTag}`;
// Search through issues (both open and closed for safety)
const response = await github.rest.search.issuesAndPullRequests({
q: `repo:${owner}/${repo} is:issue "${issueTitle}"`,
});
if (response.data.total_count > 0) {
core.info(`The issue for version ${latestTag} already exists. No action taken.`);
} else {
await github.rest.issues.create({
owner,
repo,
title: issueTitle,
labels: ['enhancement'],
body: `Update Tom Select to version **${latestTag}**.
https://cdn.jsdelivr.net/npm/tom-select@${latestTag}/dist/js/tom-select.base.js
https://cdn.jsdelivr.net/npm/tom-select@${latestTag}/dist/css/tom-select.default.min.css
Change the VENDORS.md file to trigger the library update.`
});
core.info(`New issue created for version ${latestTag}.`);
}

81
.github/workflows/tom-select-update.yml vendored Normal file
View file

@ -0,0 +1,81 @@
name: Update Tom Select Files
on:
workflow_dispatch:
push:
paths:
- 'VENDORS.md'
jobs:
tom-select-update:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Check and update vendor files
run: node .github/scripts/tom-select-update.js
- name: Commit and push to PR branch
id: commit
run: |
BASE_BRANCH="${{ github.ref_name }}"
PR_BRANCH="tom-select-update-${BASE_BRANCH}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# If there are no changes, exit without doing anything
if git diff --quiet; then
echo "No changes to vendor files."
echo "has_changes=false" >> $GITHUB_OUTPUT
exit 0
fi
# Crea o aggiorna la branch PR
git checkout -B "$PR_BRANCH"
git add -A
git commit -m "Update Tom Select files from VENDORS.md"
git push origin "$PR_BRANCH" --force
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "pr_branch=$PR_BRANCH" >> $GITHUB_OUTPUT
echo "base_branch=$BASE_BRANCH" >> $GITHUB_OUTPUT
- name: Create Pull Request via API
if: steps.commit.outputs.has_changes == 'true'
run: |
# Try to create the PR; if it already exists (422) ignore the error
HTTP_CODE=$(curl -s -o /tmp/pr_response.json -w "%{http_code}" \
-X POST \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository }}/pulls \
-d "{
\"title\": \"Update Tom Select files from VENDORS.md\",
\"body\": \"Tom Select files updated automatically after a change to \`VENDORS.md\`.\n\nPlease review the downloaded files before merging.\",
\"head\": \"${{ steps.commit.outputs.pr_branch }}\",
\"base\": \"${{ steps.commit.outputs.base_branch }}\"
}")
cat /tmp/pr_response.json
if [ "$HTTP_CODE" = "201" ]; then
echo "PR created successfully."
elif [ "$HTTP_CODE" = "422" ]; then
echo "PR already exists, updated with the new commit."
else
echo "Error creating PR: HTTP $HTTP_CODE"
exit 1
fi

30
.gitignore vendored Normal file
View file

@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
# Editor directories and files
.vscode
.vscode/*
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo
dist
.claude

View file

@ -3,11 +3,185 @@
<h2>Version 3.6.0 - ??/??/2025</h2>
<h2>Version 4.1.0 - 13/05/2026</h2>
<ul>
<li>Antispam information are now permanently saved for each message [<a href="https://github.com/micz/ThunderAI/issues/675">#675</a>].</li>
<li><i>[All APIs]</i> A summary has been added above the mail content [<a href="https://github.com/micz/ThunderAI/issues/580">#580</a>].</li>
<li><i>[All APIs]</i> Added inline auto translation for emails [<a href="https://github.com/micz/ThunderAI/issues/247">#247</a>].</li>
<li>Custom menus configuration added. Now it's possibile to define which prompts show in the ThunderAI menu, which ones in the context menu and in which order [<a href="https://github.com/micz/ThunderAI/issues/49">#49</a>, <a href="https://github.com/micz/ThunderAI/issues/184">#184</a>, <a href="https://github.com/micz/ThunderAI/issues/680">#680</a>].</li>
<li>Now the popup menu closes immediatly and the working indicator is in the button icon [<a href="https://github.com/micz/ThunderAI/issues/247">#677</a>].</li>
<li><i>[All APIs]</i> Error messages added also for background operations when the API has not been configured correctly [<a href="https://github.com/micz/ThunderAI/issues/766">#766</a>].</li>
<li><i>[Ollama API]</i> Added <i>format: json</i> option [<a href="https://github.com/micz/ThunderAI/issues/703">#703</a>].</li>
<li>Fix: The "Important Information" section in the options page now updates correctly when choosing an integration [<a href="https://github.com/micz/ThunderAI/issues/730">#730</a>].</li>
<li>In the options page now is visible if a special prompt is using a specific API integration [<a href="https://github.com/micz/ThunderAI/issues/676">#676</a>].</li>
<li>Added an antispam skip list to ensure messages from designated addresses are not forwarded to the AI [<a href="https://github.com/micz/ThunderAI/issues/743">#743</a>].</li>
<li>Fix: Correctly setting the end date for a new calendar event [<a href="https://github.com/micz/ThunderAI/issues/750">#750</a>].</li>
<li>Now it's possibile to use different date and time formats in the AI output when creating a calendar event [<a href="https://github.com/micz/ThunderAI/issues/737">#737</a>].</li>
<li>Added the <i>{%mail_full_headers%}</i> placeholder to retrieve all the email headers at once [<a href="https://github.com/micz/ThunderAI/issues/713">#713</a>].</li>
<li><i>[All APIs]</i> In the API webchat the status messages have different colors [<a href="https://github.com/micz/ThunderAI/issues/3">#3</a>].</li>
<li>Account exclusion lists for add tags and antispam are enforced only for automatic analysis of incoming emails and not for the context menu action that is always executed [<a href="https://github.com/micz/ThunderAI/issues/749">#749</a>].</li>
</ul>
<h2>Version 4.0.7 - 17/04/2026</h2>
<ul>
<li>Fix: Correctly parsing the body of HTML base64 encoded mails [<a href="https://github.com/micz/ThunderAI/issues/757">#757</a>].</li>
</ul>
<h2>Version 4.0.6 - 01/04/2026</h2>
<ul>
<li>Fix: Now it's possibile to create a tag also with accented characters in the label [<a href="https://github.com/micz/ThunderAI/issues/738">#738</a>].</li>
</ul>
<h2>Version 4.0.5 - 27/03/2026</h2>
<ul>
<li>Fix: HTML part of the mail body used in prompt is displayed as HTML code and it is not rendered. This a display fix, there is no change on how the prompt is sent to the AI [<a href="https://github.com/micz/ThunderAI/issues/711">#711</a>].</li>
<li>Fix: HTML elements added by ThunderAI (like the antispam banner) are now not present in HTML or text data placeholders [<a href="https://github.com/micz/ThunderAI/issues/710">#710</a>].</li>
<li><i>[All APIs]</i> The API webchat window now has a dynamic title [<a href="https://github.com/micz/ThunderAI/issues/696">#696</a>]</li>
</ul>
<h2>Version 4.0.4 - 26/03/2026</h2>
<ul>
<li>Fix: Correctly showing the selected model in the special prompt pages.</li>
</ul>
<h2>Version 4.0.3 - 20/03/2026</h2>
<ul>
<li>Fixed a bug in creating new tags [<a href="https://github.com/micz/ThunderAI/issues/698">#698</a>].</li>
</ul>
<h2>Version 4.0.2 - 11/03/2026</h2>
<ul>
<li>Now it's possible to automatically save the AI window position [<a href="https://github.com/micz/ThunderAI/issues/685">#685</a>].</li>
<li><i>[OpenAI API]</i> Fix: Correctly showing failed response errors during streaming [<a href="https://github.com/micz/ThunderAI/issues/690">#690</a>].</li>
<li>Fix: Correctly adding tags with non-ASCII characters [<a href="https://github.com/micz/ThunderAI/issues/689">#689</a>].</li>
<li>Improved the spacing between lines when displaying the AI response in the API webchat [<a href="https://github.com/micz/ThunderAI/issues/686">#686</a>].</li>
<li>Some minor improvments.</li>
</ul>
<h2>Version 4.0.1 - 27/02/2026</h2>
<ul>
<li>Fix: Correctly handling additional text without a placeholder [<a href="https://github.com/micz/ThunderAI/issues/681">#681</a>].</li>
</ul>
<h2>Version 4.0.0 - 24/02/2026</h2>
<ul>
<li>ThunderAI is now compatible only with Thunderbird 140 and later [<a href="https://github.com/micz/ThunderAI/issues/616">#616</a>].</li>
<li><i>[All APIs]</i> It's now possibile to define a specific API integration for calendar and task recognition [<a href="https://github.com/micz/ThunderAI/issues/498">#498</a>].</li>
<li>Added a new model selector with a search functionality to dynamically filter the list [<a href="https://github.com/micz/ThunderAI/issues/603">#603</a>].</li>
<li><i>[All APIs]</i> Added a special prompt to summarize one or more emails, using a context menu command [<a href="https://github.com/micz/ThunderAI/issues/615">#615</a>]. Thanks to <a href="https://github.com/gdkrmr">Guido Kraemer</a> for his great work on this feature.</li>
<li><i>[All APIs]</i> "Analyze for spam" and "Add tags" context menu items are always shown when the corresponding feature is enabled [<a href="https://github.com/micz/ThunderAI/issues/609">#609</a>].</li>
<li><i>[OpenAI Comp API][Ollama API]</i> Asking for the single host for permission to avoid CORS errors, instead of <i>all_urls</i>, as requested by the Thunderbird Review Team [<a href="https://github.com/micz/ThunderAI/issues/524">#524</a>].</li>
<li>Fix: Using also the mail folder owner to search for the right identity to use when composing a reply [<a href="https://github.com/micz/ThunderAI/issues/627">#627</a>].</li>
<li>Context menu items are always ordered alfabetically [<a href="https://github.com/micz/ThunderAI/issues/630">#630</a>].</li>
<li>The prompt export now includes an option to incorporate specific API settings, when present [<a href="https://github.com/micz/ThunderAI/issues/624">#624</a>].</li>
<li>Added the <i>{%mail_text_body_or_selected%}</i> placeholder to retrieve the selected text or the full text body of the email if no selection is present [<a href="https://github.com/micz/ThunderAI/issues/641">#641</a>].</li>
<li>Added the <i>{%mail_html_body_or_selected%}</i> placeholder to retrieve the selected HTML or the full HTML body of the email if no selection is present [<a href="https://github.com/micz/ThunderAI/issues/641">#641</a>].</li>
<li><i>[All APIs]</i> Added an option to get a calendar event without selecting some text, but using the full text body of the email [<a href="https://github.com/micz/ThunderAI/issues/518">#518</a>].</li>
<li><i>[All APIs]</i> Added a new menu item to create a calendar event from the text saved in the clipboard [<a href="https://github.com/micz/ThunderAI/issues/362">#362</a>].</li>
<li>Added a button to copy a prompt in the Custom Prompts page [<a href="https://github.com/micz/ThunderAI/issues/598">#598</a>].</li>
<li><i>[All APIs]</i> Showing the spam filter info at the top of the message. The data is saved only for the session in which the message has been checked for spam [<a href="https://github.com/micz/ThunderAI/issues/506">#506</a>, <a href="https://github.com/micz/ThunderAI/issues/658">#658</a>].</li>
<li>Fix: Now it's possibile to use multiple <i>additional_text</i> placeholders in a single prompt, also using custom placeholders [<a href="https://github.com/micz/ThunderAI/issues/554">#554</a>].</li>
<li>When using the <i>additional_text</i> placeholder is now possibile to specify an ID that will be shown in the form asking for the text [<a href="https://github.com/micz/ThunderAI/issues/525">#525</a>].</li>
<li><i>[ChatGPT Web]</i> Added an option to define a custom time to wait for the page load. Sometimes, on slow PCs, the ChatGPT page loads slowly and ThunderAI inject its content too early. With this option you can adjust the waiting time [<a href="https://github.com/micz/ThunderAI/issues/634">#634</a>].</li>
</ul>
<h2>Version 3.8.5 - 22/02/2026</h2>
<ul>
<li>Fix: Correctly showing email addresses when using mail headers in data placeholders [<a href="https://github.com/micz/ThunderAI/issues/672">#672</a>].</li>
</ul>
<h2>Version 3.8.4 - 10/02/2026</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [<a href="https://github.com/micz/ThunderAI/issues/646">#646</a>].</li>
</ul>
<h2>Version 3.8.3 - 22/01/2026</h2>
<ul>
<li>Fix: Correctly saving the API settings in new custom prompts [<a href="https://github.com/micz/ThunderAI/issues/623">#623</a>].</li>
<li>Japanese (ja) translation added, thanks to <a href="https://hosted.weblate.org/user/watya1/">Taichi Ito</a>.</li>
</ul>
<h2>Version 3.8.2 - 20/01/2026</h2>
<ul>
<li>Fix: Correctly saving the enabled status in custom prompts [<a href="https://github.com/micz/ThunderAI/issues/621">#621</a>].</li>
</ul>
<h2>Version 3.8.1 - 20/01/2026</h2>
<ul>
<li><i>[OpenAI API]</i> Fix: Correctly sending the prompt after opening the chat window [<a href="https://github.com/micz/ThunderAI/issues/620">#620</a>].</li>
</ul>
<h2>Version 3.8.0 - 16/01/2026</h2>
<ul>
<li><i>[All APIs]</i> Now it is possible to define an API and its settings for any custom prompt. This allows anyone to use different AI providers for different prompts [<a href="https://github.com/micz/ThunderAI/pull/102">#102</a>].</li>
<li><i>[All APIs]</i> When using special prompts (like automatically adding tags or the spam filter) with a specific API integration, all the settings for that integration can be specific. In this way you can use different api keys for the same integration, or different system prompt or temperature [<a href="https://github.com/micz/ThunderAI/pull/590">#590</a>].</li>
<li><i>[All APIs]</i> Added the temperature parameter [<a href="https://github.com/micz/ThunderAI/issues/561">#561</a>].</li>
<li><i>[OpenAI API]</i> Model filtering improved when choosing a model in the options page.</li>
<li><i>[OpenAI API]</i> Now using the new Responses API [<a href="https://github.com/micz/ThunderAI/issues/407">#407</a>].</li>
<li>It is now possible to define a custom placeholder with dynamic data to retrieve any header present in the current email [<a href="https://github.com/micz/ThunderAI/issues/527">#527</a>].</li>
<li><i>[All APIs]</i> The configuration information reported in the webchat API has been improved for all integrations.</li>
<li>Spanish (es) translation added, thanks to <a href="https://hosted.weblate.org/user/gerardo.sobarzo/">Gerardo Sobarzo</a>, <a href="https://hosted.weblate.org/user/arendon/">Andrés Rendón Hernández</a>, <a href="https://hosted.weblate.org/user/ErickLimonG/">Erick Limon</a>.</li>
<li>Swedish (sv) translation added, thanks to <a href="https://hosted.weblate.org/user/Andy_tb/">Andreas Pettersson</a>.</li>
<li>Various fixes.</li>
</ul>
<h2>Version 3.7.9 - 06/01/2026</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: Correctly getting the job completion [<a href="https://github.com/micz/ThunderAI/issues/607">#607</a>].</li>
</ul>
<h2>Version 3.7.8 - 18/12/2025</h2>
<ul>
<li>Greek (el) translation added, thanks to <a href="https://github.com/christoskaterini">ChristosK.</a>.</li>
</ul>
<h2>Version 3.7.7 - 14/12/2025</h2>
<ul>
<li><i>[Claude API][OpenAI API]</i> Fix: asking required permissions before fetching models [<a href="https://github.com/micz/ThunderAI/issues/558">#558</a>].</li>
<li><i>[Google Gemini API][Ollama API][OpenAI API][OpenAI Comp API]</i> Fix: improved error handling when parsing responses [<a href="https://github.com/micz/ThunderAI/issues/550">#550</a>].</li>
</ul>
<h2>Version 3.7.6 - 08/12/2025</h2>
<ul>
<li><i>[Claude API]</i> Added the System Prompt configuration option [<a href="https://github.com/micz/ThunderAI/issues/549">#549</a>].</li>
<li><i>[ChatGPT Web]</i> Fix: correctly showing the input field after an update in the HTML page from OpenAI [<a href="https://github.com/micz/ThunderAI/issues/556">#556</a>].</li></li>
</ul>
<h2>Version 3.7.5 - 22/10/2025</h2>
<ul>
<li><i>[OpenAI API]</i> Fixed a bug when handling responses without choices [<a href="https://github.com/micz/ThunderAI/issues/535">#535</a>].</li>
</ul>
<h2>Version 3.7.4 - 20/10/2025</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fixed a bug preventing the ChatGPT web interface from working in new installs [<a href="https://github.com/micz/ThunderAI/issues/534">#534</a>].</li>
</ul>
<h2>Version 3.7.3 - 16/10/2025</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: Correctly managing custom projects in any condition [<a href="https://github.com/micz/ThunderAI/issues/520">#520</a>].</li>
<li><i>[OpenAI API]</i> Added an optional permission for the OpenAI API endpoint to avoid a CORS errors [<a href="https://github.com/micz/ThunderAI/issues/529">#529</a>].</li>
</ul>
<h2>Version 3.7.2 - 03/10/2025</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: Not showing the force complete hint if the prompt has not been sent.</li>
<li><i>[ChatGPT Web]</i> Fix: Correctly getting when ChatGPT has finished sending the response even when using custom projects.</li>
<li><i>[ChatGPT Web]</i> Fix: Under certain conditions, asking for additional text prevents ThunderAI from sending the prompt to ChatGPT [<a href="https://github.com/micz/ThunderAI/issues/522">#522</a>].</li>
</ul>
<h2>Version 3.7.1 - 26/09/2025</h2>
<ul>
<li><i>[Google Gemini API]</i> Fix: Correctly handling empty responses [<a href="https://github.com/micz/ThunderAI/issues/514">#514</a>].</li>
</ul>
<h2>Version 3.7.0 - 18/09/2025</h2>
<ul>
<li><i>[All APIs]</i> It's now possibile to define a list of tags to be used when autotagging received emails [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>]. The tags are are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/289">#289</a>].</li>
<li><i>[All APIs]</i> The prompt id and name are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>].</li>
<li><i>[All APIs]</i> It's now possibile to define a specific API integration for spamfilter and auto tagging [<a href="https://github.com/micz/ThunderAI/issues/438">#438</a>].</li>
<li>Added the <i>{%mail_attachments_info%}</i> placeholder to retrieve the name, type and file size of the mail attachments [<a href="https://github.com/micz/ThunderAI/issues/446">#446</a>].</li>
<li><i>[Google Gemini API]</i> Support for the thinkingBudget parameter has been added [<a href="https://github.com/micz/ThunderAI/issues/494">#494</a>].</li>
<li><i>[OpenAI Comp API]</i> Added DeepSeek configuration [<a href="https://github.com/micz/ThunderAI/issues/486">#486</a>].</li>
<li><i>[ChatGPT Web]</i> Added a message to explain to click on "Force completion" if the ChatGPT job is not done after 7 seconds [<a href="https://github.com/micz/ThunderAI/issues/419">#419</a>].</li>
<li>Anthropic API renamed to Claude API [<a href="https://github.com/micz/ThunderAI/issues/510">#510</a>].</li>
<li>Various code improvements and minor bugs fixed.</li>
</ul>
<h2>Version 3.6.1 - 23/08/2025</h2>
<ul>
<li><i>[OpenAI Comp API]</i> Perplexity configuration fixed [<a href="https://github.com/micz/ThunderAI/issues/461">#461</a>].</li>
<li><i>[OpenAI Comp API]</i> Added a button to clear the models list [<a href="https://github.com/micz/ThunderAI/issues/472">#472</a>].</li>
<li><i>[ChatGPT Web]</i> Fix: Any &lt;br&gt; tag in the response is now replaced with a line break [<a href="https://github.com/micz/ThunderAI/issues/462">#462</a>].</li>
<li><i>[ChatGPT Web]</i> Models list updated. [<a href="https://github.com/micz/ThunderAI/issues/464">#464</a>].</li>
<li><i>[ChatGPT Web]</i> Improved how the line breaks are rendered in the ChatGPT web page [<a href="https://github.com/micz/ThunderAI/issues/482">#482</a>].</li>
<li><i>[All APIs]</i> Fix: If the incoming email has no text only part, the html part is used [<a href="https://github.com/micz/ThunderAI/issues/470">#470</a>].</li>
<li><i>[All APIs]</i> Fix: Improved the extraction of the plain text from html emails [<a href="https://github.com/micz/ThunderAI/issues/469">#469</a>].</li>
<li><i>[All APIs]</i> Fix: Improved how the line breaks are rendered in the AI chat [<a href="https://github.com/micz/ThunderAI/issues/469">#469</a>].</li>
<li><i>[All APIs]</i> If the option to use only existing tags is enabled, this now works also when adding tags manually using the ThunderAI menu [<a href="https://github.com/micz/ThunderAI/issues/475">#475</a>].</li>
<li><i>[All APIs][ChatGPT Web]</i> Fix: Correctly showing and hiding the context menu when changing connection type.</li>
</ul>
<h2>Version 3.6.0 - 30/07/2025</h2>
<ul>
<li>Now it's possibile to define custom data placeholders to be used in custom prompts [<a href="https://github.com/micz/ThunderAI/issues/156">#156</a>].</li>
<li>Improved the handling of HTML and line breaks between the email text and the AI Chat.</li>
<li>When replying, it's now possibile to choose a different reply type (between "all" or "sender only") directly in the AI chat window [<a href="https://github.com/micz/ThunderAI/issues/372">#372</a>].</li>
<li>Added a new default prompt for replying to emails, which asks for a custom command each time it's used [<a href="https://github.com/micz/ThunderAI/issues/444">#444</a>].</li>
<li><i>[All APIs]</i> Added an option to choose to exclude a tag only with an exact match in the excluded words list [<a href="https://github.com/micz/ThunderAI/issues/395">#395</a>].</li>
<li><i>[OpenAI API]</i> Added an option to enable the OpenAI storage for API requests [<a href="https://github.com/micz/ThunderAI/issues/406">#406</a>].</li>
<li><i>[OpenAI API]</i> In the AI chat page, the initial configuration now also displays the storage setting and the "Developer Messages" [<a href="https://github.com/micz/ThunderAI/issues/430">#430</a>].</li>
@ -17,12 +191,25 @@
<li><i>[OpenAI Comp API]</i> Added Perplexity configuration [<a href="https://github.com/micz/ThunderAI/issues/405">#405</a>].</li>
<li><i>[OpenAI Comp API]</i> Added OpenRouter configuration [<a href="https://github.com/micz/ThunderAI/issues/401">#401</a>].</li>
<li>Traditional Chinese (zh_Hant) translation added, thanks to <a href="https://github.com/evez">evez</a>.</li>
<li>Russian (ru) translation added, thanks to <a href="https://hosted.weblate.org/user/law820314/">Maksim</a>.</li>
<li>Some English typing errors have been fixed [<a href="https://github.com/micz/ThunderAI/issues/422">#422</a>].</li>
<li>...</li>
</ul>
<h2>Version 3.5.5 - 21/07/2025</h2>
<ul>
<li><i>[All APIs]</i> Fix: Autotag and Antispam filter working again [<a href="https://github.com/micz/ThunderAI/issues/449">#449</a>].</li>
</ul>
<h2>Version 3.5.4 - 13/06/2025</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: Changed again how to detect when the response is completed.</li>
<li><i>[ChatGPT Web]</i> Fix: Auto scroll to bottom works again.</li>
</ul>
<h2>Version 3.5.3 - 10/06/2025</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: Correctly detecting when the response is completed.</li>
</ul>
<h2>Version 3.5.2 - 05/06/2025</h2>
<ul>
<li><i>[ChatGPT Web]</i> Fix: correctly hiding the model warning message when forcing to send the prompt [<a href="https://github.com/micz/ThunderAI/issues/410">#410</a>].</li>
<li><i>[ChatGPT Web]</i> Fix: Correctly hiding the model warning message when forcing to send the prompt [<a href="https://github.com/micz/ThunderAI/issues/410">#410</a>].</li>
<li><i>[ChatGPT Web]</i> Fix: ThunderAI is now working also with a free account [<a href="https://github.com/micz/ThunderAI/issues/408">#408</a>].</li>
<li><i>[ChatGPT Web]</i> Fix: Correctly showing a warning message to a not logged in user [<a href="https://github.com/micz/ThunderAI/issues/411">#411</a>].</li>
<li><i>[ChatGPT Web]</i> Improved the model not found message [<a href="https://github.com/micz/ThunderAI/issues/413">#413</a>].</li>
@ -304,7 +491,7 @@
<li>Added a better error message when there is an error fetching models.</li>
<li>When selecting a correct model in the options page, the field is no more highlighted in red [<a href="https://github.com/micz/ThunderAI/issues/100">#100</a>].</li>
<li>When using the ChatGPT API, the double quotes at the beginning and end of the response are removed [<a href="https://github.com/micz/ThunderAI/issues/99">#99</a>].</li>
<li><i>[ChatGPT Web]</i>"Keep formatting" option removed.</li>
<li><i>[ChatGPT Web]</i> "Keep formatting" option removed.</li>
</ul>
<h2>Version 2.0.1 - 09/08/2024</h2>
<ul>

65
CLAUDE.md Normal file
View file

@ -0,0 +1,65 @@
# ThunderAI - Claude Code Guide
## Project Overview
ThunderAI is a **Thunderbird WebExtension (Manifest V2)** that integrates multiple AI providers (ChatGPT Web, OpenAI API, Google Gemini, Claude/Anthropic, Ollama, and OpenAI-compatible APIs) directly into the Thunderbird email client.
- **Extension ID:** `thunderai@micz.it`
- **Min Thunderbird:** 140.0+
- **Language:** Plain ES6+ JavaScript modules — no build tools, no transpilation, no npm
- **License:** GPLv3
## Key Rules
1. **Localization:** Modify ONLY `_locales/en/messages.json`. All other locale files are managed via Weblate — never touch them.
2. **No build system:** There is no bundler, compiler, or package manager. All JS files are plain ES6 modules loaded directly by the browser engine.
3. **Module imports:** Use relative paths with `.js` extension (e.g., `import { foo } from '../js/mzta-utils.js'`).
4. **Placeholder format:** Placeholders in prompt text use the `{%placeholder_id%}` syntax (e.g., `{%mail_text_body_or_selected%}`).
5. **No test suite:** There is no automated test framework. Testing is done manually in Thunderbird.
6. **Settings defaults:** All new preferences must be added to `options/mzta-options-default.js` in `prefs_default`.
7. **Keep spec files up to date:** When making code changes that affect a subsystem described in claude-spec/, update the relevant spec file to reflect the new behavior. Read the spec before modifying, update it after.
## Directory Map
```
/
├── mzta-background.js # Background script (main entry point)
├── mzta-background.html # Loads the background script
├── manifest.json # Extension manifest
├── js/ # Core modules
│ ├── api/ # AI API integration modules
│ ├── workers/ # Web Workers (one per API provider)
│ ├── lib/ # Third-party libraries (diff.js)
│ └── mzta-*.js # Core utilities, menus, prompts, placeholders
├── options/ # Settings UI
│ ├── mzta-options.html/.js/.css
│ ├── mzta-options-default.js # ALL default preference values
│ └── mzta-release-notes.html
├── pages/ # Feature-specific settings pages
│ ├── addtags/
│ ├── customprompts/
│ ├── customdataplaceholders/
│ ├── get-calendar-event/
│ ├── get-task/
│ ├── spamfilter/
│ ├── summarize/
│ └── onboarding/
├── popup/ # Popup menu (shown on toolbar click)
│ └── mzta-popup.html/.js/.css
├── _locales/ # Localization
│ ├── en/messages.json # ← ONLY THIS FILE is edited directly
│ └── [15 other languages managed by Weblate]
├── images/ # Icons and graphical assets
└── api_webchat/ # Web chat API interface
```
## Spec Files
For detailed documentation see [`claude-spec/`](claude-spec/):
- [01-architecture.md](claude-spec/01-architecture.md) — Module structure and data flow
- [02-prompts.md](claude-spec/02-prompts.md) — Prompt system (types, actions, properties)
- [03-placeholders.md](claude-spec/03-placeholders.md) — Placeholder system
- [04-api-integrations.md](claude-spec/04-api-integrations.md) — AI provider integrations
- [05-options.md](claude-spec/05-options.md) — Settings and preferences system
- [06-localization.md](claude-spec/06-localization.md) — i18n rules and workflow
- [99-thunderbird-team-spec.md](claude-spec/99-thunderbird-team-spec.md) — Thunderbird WebExtensions development guidelines (API usage, experiments, review requirements)

View file

@ -1,10 +1,15 @@
cs
de
el
en
es
fr
hr
it
ja
pl
pt-br
cs
ru
sv
zh_Hans
zh_Hant

View file

@ -1,6 +1,6 @@
# ![ThunderAI icon](images/icon-32px.png "ThunderAI") ThunderAI
ThunderAI is a Thunderbird Addon that uses the capabilities of ChatGPT, Google Gemini, Anthropic or Ollama to enhance email management.
ThunderAI is a Thunderbird Addon that uses the capabilities of ChatGPT, Google Gemini, Claude or Ollama to enhance email management.
It enables users to analyse, write, correct, assign tags, create calendar events or tasks and optimize their emails, facilitating more effective and professional communication.
@ -31,8 +31,15 @@ Using an API integration, you can activate some automatic features:
> <br>
>
> - **Google Gemini**
> - You can use also the _System Instructions_ option if needed.
> - You can use also the _System Instructions_ and _thinkingBudget_ options if needed.
>
>
> <br>
>
> - **Claude API**
> - You need to grant the permission "_Access your data for sites in the https://anthropic.com domain_" to use the Claude API.
>
>
> <br>
>
> - **Using Ollama**
@ -44,14 +51,25 @@ Using an API integration, you can activate some automatic features:
> - **OpenAI Compatible API**
> - You can also use a local OpenAI Compatible API server, like LM Studio or Mistral AI!
> - There is also an option to remove the "v1" segment from the API url, if needed, and to manually set the model name if the server doesn't have a models list endpoint.
>
> <br>
>
> - **Anthropic API**
> - Use Claude directly!
> - You can also use one of these predefined configurations:
> - DeepSeek API
> - Grok API
> - Mistral API
> - OpenRouter API
> - Perplexity API
<br>
## Documentation
[Setup Guides](https://micz.it/thunderbird-addon-thunderai/guides/) - Step-by-step guides to connect ThunderAI to the AI backend of your choice, from ChatGPT to local models with Ollama.
[Custom Prompt Tutorial](https://micz.it/thunderbird-addon-thunderai/tutorial/) - Learn how to build your first custom prompt from scratch, combining placeholders and user input to automate your email replies.
[ThunderAI Prompt Architect](https://chatgpt.com/g/g-69b6b11c89b88191a6798be6e97025f1-thunder-ai-prompt-architect) - Let ChatGPT help you crafting your custom prompts. Thanks to [Paweł](https://github.com/PawelKinczyk) for this tool!
<br>
## Translations
@ -59,6 +77,8 @@ Do you want to help translate this addon?
[Find out how!](https://micz.it/thunderbird-addon-thunderai/translate/)
<br>
## Changelog
@ -80,14 +100,20 @@ Are you using this addon in your Thunderbird?
## Attributions
### Translations
- Chinese (Simplified): [jeklau](https://github.com/jeklau) <img src="https://micz.it/weblate/thunderai/zh_Hans.svg">
- Chinese (Traditional): [evez](https://github.com/evez) <img src="https://micz.it/weblate/thunderai/zh_Hant.svg">
- Czech (cs): [Fjuro](https://hosted.weblate.org/user/Fjuro/), [Jaroslav Staněk](https://hosted.weblate.org/user/jaroush/) <img src="https://micz.it/weblate/thunderai/cs.svg">
- French (fr): Generated automatically, [Noam](https://github.com/noam-sc) <img src="https://micz.it/weblate/thunderai/fr.svg">
- German (de): Generated automatically <img src="https://micz.it/weblate/thunderai/de.svg">
- Italian (it): [Mic](https://github.com/micz/) <img src="https://micz.it/weblate/thunderai/it.svg">
- Polski (pl): [neexpl](https://github.com/neexpl), [makkacprzak](https://github.com/makkacprzak) <img src="https://micz.it/weblate/thunderai/pl.svg">
- Português Brasileiro (pt-br): Bruno Pereira de Souza <img src="https://micz.it/weblate/thunderai/pt-br.svg">
- Brazilian Portuguese - Português Brasileiro (pt-br): Bruno Pereira de Souza <img src="https://micz.it/weblate/thunderai/pt-br.svg">
- Chinese (Simplified) - Jiǎntǐ Zhōngwén (简体中文) (zh_Hans): [jeklau](https://github.com/jeklau), [Min9X1n](https://github.com/Min9X1n) <img src="https://micz.it/weblate/thunderai/zh_Hans.svg">
- Chinese (Traditional) - Fántǐ Zhōngwén (繁體中文) (zh_Hant): [evez](https://github.com/evez) <img src="https://micz.it/weblate/thunderai/zh_Hant.svg">
- Croatian - Hrvatski (hr): Petar Jedvaj <img src="https://micz.it/weblate/thunderai/hr.svg">
- Czech - Čeština (cs): [Fjuro](https://hosted.weblate.org/user/Fjuro/), [Jaroslav Staněk](https://hosted.weblate.org/user/jaroush/) <img src="https://micz.it/weblate/thunderai/cs.svg">
- French - Français (fr): Generated automatically, [Noam](https://github.com/noam-sc) <img src="https://micz.it/weblate/thunderai/fr.svg">
- German - Deutsch (de): Generated automatically <img src="https://micz.it/weblate/thunderai/de.svg">
- Greek - Elliniká (Ελληνικά) (el): [ChristosK.](https://github.com/christoskaterini) <img src="https://micz.it/weblate/thunderai/el.svg">
- Italian - Italiano (it): [Mic](https://github.com/micz) <img src="https://micz.it/weblate/thunderai/it.svg">
- Japanese - Nihongo (日本語) (ja): [Taichi Ito](https://github.com/watya1) <img src="https://micz.it/weblate/thunderai/ja.svg">
- Polish - Polski (pl): [neexpl](https://github.com/neexpl), [makkacprzak](https://github.com/makkacprzak) <img src="https://micz.it/weblate/thunderai/pl.svg">
- Russian - Russkiy (русский) (ru): [Maksim](https://hosted.weblate.org/user/law820314/) <img src="https://micz.it/weblate/thunderai/ru.svg">
- Spanish - Español (es): [Gerardo Sobarzo](https://hosted.weblate.org/user/gerardo.sobarzo/), [Andrés Rendón Hernández](https://hosted.weblate.org/user/arendon/), [Erick Limon](https://hosted.weblate.org/user/ErickLimonG/) <img src="https://micz.it/weblate/thunderai/es.svg">
- Swedish - Svenska (sv): [Andreas Pettersson](https://hosted.weblate.org/user/Andy_tb/), [Luna Jernberg](https://hosted.weblate.org/user/bittin1ddc447d824349b2/) <img src="https://micz.it/weblate/thunderai/sv.svg">
<br>
Do you want to help translate this addon? [Find out how!](https://micz.it/thunderbird-addon-thunderai/translate/) <br>
@ -101,6 +127,13 @@ _The language status represents the percentage of translated strings in the late
- <a href="https://loading.io">loading.io</a> for the loading SVGs
- [Fluent Design System](https://www.iconfinder.com/fluent-designsystem) for the Custom Prompts table sorting icons
- [JessiGue](https://www.flaticon.com/authors/jessigue) for the show/hide icon for api key fields
- [Iconka.com](https://www.iconarchive.com/artist/iconka.html) for the autotag context menu icon
- [Icojam](https://www.iconarchive.com/artist/icojam.html) for the spam filter context menu icon
- [Roundicons](https://www.flaticon.com/authors/roundicons) for the summarize context menu icon
- [HideMau](https://www.flaticon.com/authors/hidemaru) for the ai summarize icon
- [Hilmy Abiyyu A.](https://www.flaticon.com/authors/hilmy-abiyyu-a) for the ai translate and context menu icons
- [bearicons](https://www.flaticon.com/authors/bearicons) for the empty context menu icon
- [meaicon](https://www.flaticon.com/authors/meaicon) for the add task context menu icon
<br>

11
VENDORS.md Normal file
View file

@ -0,0 +1,11 @@
file: pages\_lib\list.js
source: https://raw.githubusercontent.com/javve/list.js/v2.3.1/dist/list.js
file: pages\_lib\tom-select.base.js
source: https://cdn.jsdelivr.net/npm/tom-select@v2.6.1/dist/js/tom-select.base.js
file: pages\_lib\tom-select.default.min.css
source: https://cdn.jsdelivr.net/npm/tom-select@v2.6.1/dist/css/tom-select.default.min.css
file: js\lib\diff.js
source: https://cdnjs.cloudflare.com/ajax/libs/jsdiff/7.0.0/diff.js

200
_locales/bg/messages.json Normal file
View file

@ -0,0 +1,200 @@
{
"extensionDescription": {
"message": "Използвайте ChatGPT, Google Gemini, Claude или Ollama, за да подобрите вашите имейли!"
},
"menu_title": {
"message": "ИИ"
},
"prompt_lang": {
"message": "Отговорено за"
},
"prompt_reply": {
"message": "Отговор на този имейл"
},
"prompt_reply_advanced": {
"message": "Отговор към тази нишка"
},
"prompt_reply_custom_command": {
"message": "Отговаряне с команда"
},
"prompt_rewrite_polite": {
"message": "Пренаписване по-учтиво"
},
"prompt_rewrite_formal": {
"message": "Пренаписване по-формално"
},
"prompt_classify": {
"message": "Класифициране"
},
"prompt_translate_this": {
"message": "Превеждане"
},
"prompt_this": {
"message": "Поискайте това"
},
"prompt_selection_needed": {
"message": "Селектирайте текст, за да продължите!"
},
"customPrompts_managePrompts": {
"message": "Управление на подкани"
},
"more_info_string": {
"message": "Повече информация"
},
"customPrompts_managePrompts_info_default": {
"message": "Подканите по подразбиране не са редактируеми. Можете да ги изключите, да копирате текста им и да го поставите в нова, модифицирана версия."
},
"customPrompts_managePrompts_info_default_2": {
"message": "Можете да внесете и изнесете подканите. Съществуващите подкани със същото ID ще бъдат презаписани. Подканите с нови ID-та ще бъдат добавени."
},
"customPrompts_managePrompts_info_default_3": {
"message": "Ако всичко е правилно, след внасянето натиснете бутона \"Запази всичко\"."
},
"customPrompts_start_saving": {
"message": "Запазване на подканите..."
},
"customPrompts_reindexing_list": {
"message": "Преиндексиране на списъка..."
},
"customPrompts_filtering_prompts": {
"message": "Филтриране на подканите..."
},
"customPrompts_saving_default_prompts": {
"message": "Запазване на подкани по подразбиране..."
},
"customPrompts_saving_custom_prompts": {
"message": "Запазване на персонализирани подкани..."
},
"customPrompts_reloading_menus": {
"message": "Презареждане на менюта..."
},
"customPrompts_saved": {
"message": "Подканите са запазени!"
},
"customPrompts_form_label_ID": {
"message": "ID"
},
"customPrompts_form_label_ID_rules": {
"message": "Трябва да е уникално, с малки букви и без разстояния"
},
"customPrompts_form_label_Name": {
"message": "Име"
},
"customPrompts_form_label_Text": {
"message": "Текст на подкана"
},
"customPrompts_form_label_Action": {
"message": "Действие"
},
"customPrompts_form_label_need_selected": {
"message": "Необходима е селекция на текст"
},
"customPrompts_form_label_need_signature": {
"message": "Винаги добавяй подпис"
},
"customPrompts_form_label_need_custom_text": {
"message": "Поискай допълнителен текст"
},
"customPrompts_form_label_enabled": {
"message": "Разрешено"
},
"customPrompts_form_label_use_diff_viewer": {
"message": "Активиране на инструмента за сравнение на текст"
},
"customPrompts_form_label_use_diff_viewer_title": {
"message": "Инструментът за сравнение на текст може да бъде избран, когато действието е зададено на „Замести текст“."
},
"customPrompts_form_required_fields": {
"message": "Задължително поле"
},
"customPrompts_btnEdit": {
"message": "Редакция"
},
"customPrompts_btnCancel": {
"message": "Откажи"
},
"customPrompts_btnOK": {
"message": "ОК"
},
"customPrompts_btnDelete": {
"message": "Изтрий"
},
"customPrompts_btnDelete_confirmText": {
"message": "Сигурни ли сте, че искате да изтриете този елемент?"
},
"customPrompts_unsaved_changes": {
"message": "Има незапазени промени!"
},
"btnSaveAll_string": {
"message": "Запази всичко"
},
"btnNew_string": {
"message": "Добави нов"
},
"customPrompts_btnAddNewCommit": {
"message": "Добави подканата"
},
"customPrompts_add_to_menu": {
"message": "Добави към меню"
},
"customPrompts_add_to_menu_always": {
"message": "Винаги"
},
"customPrompts_add_to_menu_reading": {
"message": "Четене на писмо"
},
"customPrompts_add_to_menu_composing": {
"message": "Писане на писмо"
},
"customPrompts_close_button": {
"message": "Бутон за изключване"
},
"customPrompts_do_reply": {
"message": "Отговори"
},
"customPrompts_substitute_text": {
"message": "Замени тескт"
},
"chatgpt_win_working": {
"message": "В процес на работа..."
},
"chatgpt_win_job_completed": {
"message": "Завършено!"
},
"chatgpt_win_job_completed_select": {
"message": "Изберете текста, който искате да използвате, и щракнете върху бутона."
},
"chatgpt_win_get_answer": {
"message": "Използвайте избрания отговор"
},
"chatgpt_win_close": {
"message": "Затвори"
},
"chatgpt_textarea_not_found_error": {
"message": "Изглежда, че страницата на ChatGPT се зарежда твърде бавно. Ако зареждането приключи, щракнете върху бутона вдясно. Ако проблемът продължава, моля, проверете състоянието на услугата."
},
"chatgpt_btn_retry": {
"message": овторeн опит"
},
"chatgpt_sendbutton_not_found_error": {
"message": "Кликнете върху бутона за изпращане, за да изпратите подканата."
},
"chatgpt_user_not_logged_in": {
"message": "Не сте влезли в ChatGPT. Моля, влезте с вашите идентификационни данни, затворете прозореца на ChatGPT и след това повторете действието, което сте опитали. След това ще останете влезли."
},
"chatgpt_win_model_warning": {
"message": "По някаква причина не е възможно да се провери дали е зареден правилният модел. Засега можете да натиснете синия бутон, за да продължите."
},
"chatgpt_win_custom_text": {
"message": "Въведете тук допълнителния текст за подканата."
},
"chatgpt_win_send": {
"message": "Изпрати"
},
"warn_API_needed": {
"message": "За да използвате тази функция, ви е необходима API интеграция, а не ChatGPT Web интеграция. Можете да дефинирате конкретен API на страницата с настройки на функцията, като първо поставите отметка в квадратчето по-горе и след това щракнете върху бутона отляво."
},
"prefs_google_gemini_thinking_budget": {
"message": "Бюджет за мислене"
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

1798
_locales/el/messages.json Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
"message": "Respondi per"
},
"extensionDescription": {
"message": "Uzu ChatGPT, Google Gemini, Anthropic aŭ Ollama por poluri viajn retpoŝtajn mesaĝojn!"
"message": "Uzu ChatGPT, Google Gemini, Claude aŭ Ollama por poluri viajn retpoŝtajn mesaĝojn!"
},
"prompt_rewrite_formal": {
"message": "Reverki formale"
@ -38,7 +38,7 @@
"From": {
"message": "De"
},
"spamfilter_not_moved": {
"no_string": {
"message": "Ne"
},
"apiwebchat_stopping": {
@ -65,9 +65,6 @@
"prompt_reply_advanced": {
"message": "Respondu al ĉi tiu fadeno"
},
"prompt_summarize_this": {
"message": "Resumu ĉi tion"
},
"prompt_translate_this": {
"message": "Traduku ĉi tion"
},
@ -122,7 +119,7 @@
"Explanation": {
"message": "Klarigo"
},
"spamfilter_moved": {
"yes_string": {
"message": "Jes"
},
"apiwebchat_you": {
@ -151,5 +148,26 @@
},
"Ollama_Models_Fetch": {
"message": "Ĝisdatigi liston de modeloj Ollama"
},
"prefs_OptionText_reply_all": {
"message": "Respondi al ĉiuj"
},
"prefs_OptionText_reply_sender": {
"message": "Respondi al sendinto"
},
"prefs_OptionText_reply_type": {
"message": "Speco de respondo"
},
"SelectAll": {
"message": "Elekti ĉion"
},
"DeselectAll": {
"message": "Malelekti ĉion"
},
"prompt_reply_custom_command": {
"message": "Respondi per komando..."
},
"customPrompts_substitute_text": {
"message": "Anstataŭigi tekston"
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"extensionDescription": {
"message": "Koristite ChatGPT, Google Gemini, Anthropic ili Ollama kako bi poboljšali vaše e-poruke!",
"message": "Koristite ChatGPT, Google Gemini, Claude ili Ollama kako bi poboljšali vaše e-poruke!",
"description": "Description of the extension."
},
"menu_title": {
@ -24,9 +24,6 @@
"prompt_classify": {
"message": "Klasificiraj"
},
"prompt_summarize_this": {
"message": "Sažmi ovo"
},
"prompt_translate_this": {
"message": "Prevedi ovo"
},
@ -327,9 +324,6 @@
"chagpt_api_send_button": {
"message": "Korištenje modela"
},
"chagpt_api_connecting": {
"message": "Pokušaj povezivanja na OpenAI ChatGPT pomoću dostavljenog API ključa"
},
"Debug": {
"message": "Otklanjanje pogrešaka"
},
@ -363,12 +357,6 @@
"ollama_empty_model": {
"message": "Niste odabrali model za Ollama API. Odaberite jedan na stranici s mogućnostima."
},
"ollama_api_connecting": {
"message": "Pokušaj povezivanja na Ollama lokalni poslužitelj pomoću glavnog računala"
},
"andModel": {
"message": "i model"
},
"error_connection_interrupted": {
"message": "Veza s poslužiteljem je neočekivano prekinuta"
},
@ -399,9 +387,6 @@
"OpenAIComp_empty_model": {
"message": "Niste odabrali model za OpenAI kompatibilan API. Odaberite jedan na stranici s opcijama."
},
"OpenAIComp_api_connecting": {
"message": "Pokušaj povezivanja s OpenAI kompatibilnim API lokalnim poslužiteljem pomoću glavnog računala"
},
"OpenAIComp_api_request_failed": {
"message": "OpenAI Comp API zahtjev nije uspio"
},
@ -423,12 +408,6 @@
"prefs_OptionText_dynamic_menu_force_enter_info": {
"message": "Ako je označeno, korištenje tipkovničkog prečaca CTRL+ALT+A automatski će poslati istaknuti upit iz izbornika. U protivnom će korisniku biti prikazan naziv upita, koji će zahtijevati još jedan pritisak tipke Enter za slanje."
},
"prefs_OptionText_dynamic_menu_order_alphabet": {
"message": "Izbornik: redoslijed po abecedi"
},
"prefs_OptionText_dynamic_menu_order_alphabet_info": {
"message": "Ako je označeno, upiti u izborniku bit će poredani abecednim redom."
},
"prefs_OptionText_chatgpt_win_dims_info": {
"message": "Postavite na 0 ako ne želite odrediti veličinu prozora."
},
@ -498,9 +477,6 @@
"chatgpt_btn_model": {
"message": "Koristi trenutni model"
},
"SendingPrompt": {
"message": "Slanje upita..."
},
"AllowedValues": {
"message": "Dopuštene vrijednosti"
},
@ -516,9 +492,6 @@
"prefs_OptionText_owl_warning": {
"message": "Čini se da barem jedan od vaših računa koristi dodatak Owl for Exchange. Postoji poznati problem između Thunderbirda i Owl, koji se trenutno rješava. Trenutačno možete koristiti ThunderAI dok sastavljate e-poruke, ali ne i dok ih čitate."
},
"prefs_OptionText_chatgpt_web_model_tooltip": {
"message": "Pritisnite vrijednost da biste je postavili."
},
"prompt_reply_full_text": {
"message": "Odgovori na sljedeću e-poruku. Odgovorit samo s potrebnim tekstom i bez dodatnih komentara ili drugog teksta."
},
@ -543,11 +516,8 @@
"prompt_classify_full_text": {
"message": "Klasificiraj sljedeći tekst u smislu ljubaznosti, topline, formalnosti, asertivnosti, uvredljivosti dajući postotak za svaku kategoriju. Odgovori samo kategorijom i ocijeni bez dodatnih komentara ili drugog teksta."
},
"prompt_summarize_this_full_text": {
"message": "Sažmi sljedeću e-poruku u popis s točkama."
},
"prompt_translate_this_full_text": {
"message": "Prevedi sljedeću e-poruku na"
"message": "Prevedite donju e-poštu na {%thunderai_translate_lang%}.\n\nPravila:\n- Prevedite i predmet i tijelo e-pošte.\n- Vratite rezultat kao JSON objekt s tri polja: \"subject\", \"body\" i \"status\".\n- Ako je prijevod izvršen, status je jedan 1.\n- Ako je e-pošta napisana na jednom od ovih jezika \"{%thunderai_translate_exclude_lang%}\" ili na jeziku {%thunderai_translate_lang%}, vratite prazan niz za tijelo i predmet i postavite status na -1.\n- Nemojte dodavati objašnjenja, bilješke ili bilo kakav tekst izvan JSON-a.\n\nPredmet e-pošte: {%mail_subject%}\n\nTijelo e-pošte: {%mail_html_body%}\n\nGenerirajte odgovor isključivo u JSON formatu. Izlaz treba biti samo JSON objekt. Evo primjera JSON formata koji treba koristiti:\n{\n\"subject\": \"subject translation\",\n\"body\": \"body translation\",\n\"status\": \"status result\"\n}"
},
"prompt_this_full_text": {
"message": "Odgovori samo s potrebnim tekstom i bez dodatnih komentara ili drugog teksta."
@ -562,7 +532,7 @@
"message": "Dodaj oznake ovoj e-poruci"
},
"prompt_add_tags_full_text": {
"message": "Analiziraj sljedeći tekst e-pošte i generiraj JSON niz oznaka koje sažimaju njezin sadržaj. Koristi teme, ključne pojmove i relevantne opise kao oznake. Pobrini se da oznake budu sažete i relevantne za sadržaj poruke.\nTekst e-poruke: {%mail_text_body%}\nUzmi u obzir sljedeće pojedinosti za kontekst:\n- Šalje: {%author%}\n- Primatelji: {%recipients%}\n- CC popis: {%cc_list%}\n- Naslov: {%mail_subject%}\nTemelji oznake na tekstu poruke i kontekstu, zanemarujući nebitne informacije ili trivijalne detalje.\nGeneriraj odgovor isključivo u JSON formatu. Izlaz mora biti samo JSON niz oznaka, bez ikakvih dodatnih komentara ili teksta. Evo primjera formata koji treba koristiti:\n{\n'tags': ['tag1', 'tag2', 'tag3', 'tag4', 'tag5']\n}"
"message": "Analiziraj sljedeći tekst e-pošte i generiraj JSON niz oznaka koje sažimaju njezin sadržaj. Koristi teme, ključne pojmove i relevantne opise kao oznake. Pobrini se da oznake budu sažete i relevantne za sadržaj poruke.\nTekst e-poruke: {%mail_text_body%}\nUzmi u obzir sljedeće pojedinosti za kontekst:\n- Šalje: {%author%}\n- Primatelji: {%recipients%}\n- CC popis: {%cc_list%}\n- Naslov: {%mail_subject%}\nTemelji oznake na tekstu poruke i kontekstu, zanemarujući nebitne informacije ili trivijalne detalje.\nGeneriraj odgovor isključivo u JSON formatu. Izlaz mora biti samo JSON niz oznaka, bez ikakvih dodatnih komentara ili teksta. Evo primjera formata koji treba koristiti:\n{\n\"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]\n}"
},
"placeholder_tags_current_email": {
"message": "Oznake e-pošte"
@ -681,9 +651,6 @@
"google_gemini_api_request_failed": {
"message": "Google Gemini API zahtjev nije uspio"
},
"google_gemini_api_connecting": {
"message": "Pokušaj povezivanja na Google Gemini pomoću dostavljenog API ključa"
},
"google_gemini_empty_apikey": {
"message": "Niste dodali API ključ za Google Gemini API. Unesite jedan na stranicu s mogućnostima."
},
@ -712,7 +679,7 @@
"message": "Dodaj novi kalendarski događaj"
},
"prompt_get_calendar_event_full_text": {
"message": "Izdvoji sve relevantne detalje potrebne za generiranje kalendarskog događaja iz sljedećeg teksta. Izdvojene informacije trebaju uključivati:\n- Naslov događaja\n- Datum i vrijeme početka (uključujući vremensku zonu, ako je navedeno)\n- Datum i vrijeme završetka (uključujući vremensku zonu, ako je navedeno)\n- Cijeli dan (ako je navedeno)\n- Sudionici\nOsiguraj da su podaci oblikovani jasno i dosljedno kako bi se mogli izravno koristiti za stvaranje kalendarskog događaja.\nAko postoje relativne vremenske napomene, smatraj da su datum i vrijeme e-poruke \"{%mail_datetime%}\". Izračunajte datum i vrijeme početka na temelju ove napomene. Ako su izračunati početni datum i vrijeme raniji od \"{%current_datetime%}\", ponovno izračunaj početni datum i vrijeme koristeći \"{%current_datetime%}\" kao osnovu.\nAko trajanje nije navedeno, postavi ga na jedan sat.\nOvo su sudionici: {%author%}, {%recipients%}, {%cc_list%}. Ako je prisutna, isključi moju adresu: {%account_email_address%}.\nAko ne možeš dobiti jednu ili više potrebnih informacija, odgovori praznim nizom.\nGeneriraj odgovor samo u JSON formatu. Nemoj uključivati nikakav dodatni tekst ili objašnjenja; pruži samo JSON. Ovo je format koji će se koristiti:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Sažetak kalendarskih događaja ovdje\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOvo je tekst:\"{%selected_text%}\""
"message": "Izdvoji sve relevantne detalje potrebne za generiranje kalendarskog događaja iz sljedećeg teksta. Izdvojene informacije trebaju uključivati:\n- Naslov događaja\n- Datum i vrijeme početka (uključujući vremensku zonu, ako je navedeno)\n- Datum i vrijeme završetka (uključujući vremensku zonu, ako je navedeno)\n- Cijeli dan (ako je navedeno)\n- Sudionici\nOsiguraj da su podaci oblikovani jasno i dosljedno kako bi se mogli izravno koristiti za stvaranje kalendarskog događaja.\nAko postoje relativne vremenske napomene, smatraj da su datum i vrijeme e-poruke \"{%mail_datetime%}\". Izračunajte datum i vrijeme početka na temelju ove napomene. Ako su izračunati početni datum i vrijeme raniji od \"{%current_datetime%}\", ponovno izračunaj početni datum i vrijeme koristeći \"{%current_datetime%}\" kao osnovu.\nAko trajanje nije navedeno, postavi ga na jedan sat.\nOvo su sudionici: {%author%}, {%recipients%}, {%cc_list%}. Ako je prisutna, isključi moju adresu: {%account_email_address%}.\nAko je događaj cjelodnevni, **endDate** mora biti jedan dan nakon **startDate** s vremenom postavljenim na **\"T000000\"**.\nAko ne možeš dobiti jednu ili više potrebnih informacija, odgovori praznim nizom.\nGeneriraj odgovor samo u JSON formatu. Nemoj uključivati nikakav dodatni tekst ili objašnjenja; pruži samo JSON. Ovo je format koji će se koristiti:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Sažetak kalendarskih događaja ovdje\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOvo je tekst:\"{%mail_text_body_or_selected%}\""
},
"prefs_OptionText_get_calendar_event": {
"message": "Dodaj novi kalendarski događaj iz odabranog teksta"
@ -753,9 +720,6 @@
"calendar_opening_dialog_error": {
"message": "Pogreška pri otvaranju dijaloškog okvira kalendarskog događaja"
},
"sparks_not_installed": {
"message": "ThunderAI Sparks nije instaliran!"
},
"prefs_OptionText_add_tags_auto": {
"message": "Dodajte oznake automatski"
},
@ -777,7 +741,7 @@
"placeholder_thunderai_def_sign": {
"message": "Zadani potpis kako je određeno u mogućnostima ThunderAI."
},
"thunderai_def_lang": {
"placeholder_thunderai_def_lang": {
"message": "Zadani jezik kako je određeno u mogućnostima ThunderAI."
},
"prefs_OptionText_spamfilter": {
@ -802,7 +766,7 @@
"message": "Prepoznaj neželjenu poštu"
},
"prompt_spamfilter_full_text": {
"message": "Analiziraj sljedeću e-poruku i utvrdi je li neželjena ili ne. Razmotri čimbenike kao što su sumnjive ključne riječi, pretjerani promotivni jezik, zavaravajuće linije predmeta, zahtjevi za osobnim podacima i neobične adrese pošiljatelja.\nNavedi vrijednost od 0 (nije spam) do 100 (neželjena pošta) i objašnjenje od najviše 10 riječi.\nU slučaju nedostatka podataka poruke, postavite vrijednost na 0 (nije spam) i navedite razlog.\nGeneriraj odgovor samo u JSON formatu. Nemoj uključivati nikakav dodatni tekst ili objašnjenje; pruži samo JSON. Ovdje je format koji treba koristiti:\n{\n\"spamValue\": <cijeli broj od 0 do 100>,\n\"explanation\": \"Kratko objašnjenje vašeg obrazloženja\"\n}\nOvdje su informacije o e-poruci:\nŠalje: \"{%author%}\"\nNaslov: \"{%mail_subject%}\"\nHtml tijelo: \"{%mail_html_body%}\""
"message": "Analiziraj sljedeću e-poruku i utvrdi je li neželjena ili ne. Razmotri čimbenike kao što su sumnjive ključne riječi, pretjerani promotivni jezik, zavaravajuće linije predmeta, zahtjevi za osobnim podacima i neobične adrese pošiljatelja.\nNavedi vrijednost od 0 (nije spam) do 100 (neželjena pošta) i objašnjenje od najviše 10 riječi.\nU slučaju nedostatka podataka poruke, postavite vrijednost na 0 (nije spam) i navedite razlog.\nGeneriraj odgovor samo u JSON formatu. Nemoj uključivati nikakav dodatni tekst ili objašnjenje; pruži samo JSON. Ovdje je format koji treba koristiti:\n{\n\"explanation\": \"Kratko objašnjenje vašeg obrazloženja\",\n\"spamValue\": <cijeli broj od 0 do 100>\n}\nOvdje su informacije o e-poruci:\nŠalje: \"{%author%}\"\nNaslov: \"{%mail_subject%}\"\nHtml tijelo: \"{%mail_html_body%}\""
},
"SpamFilter_prompt_prefs_title": {
"message": "Mogućnosti filtera neželjene pošte"
@ -846,10 +810,10 @@
"Report_Date": {
"message": "Datum izvješća"
},
"spamfilter_moved": {
"yes_string": {
"message": "Da"
},
"spamfilter_not_moved": {
"no_string": {
"message": "Ne"
},
"prefs_OptionText_openai_comp_info_remote": {

17
_locales/hu/messages.json Normal file
View file

@ -0,0 +1,17 @@
{
"extensionDescription": {
"message": "Használja a ChatGPT, Google Gemini, Claude vagy Ollama modelleket, hogy még jobbá tegye emailjeit!"
},
"menu_title": {
"message": "MI"
},
"prompt_reply": {
"message": "Válasz erre az emailre"
},
"prompt_rewrite_polite": {
"message": "Újraírás udvariasabban"
},
"prompt_rewrite_formal": {
"message": "Újraírás formálisan"
}
}

File diff suppressed because it is too large Load diff

1266
_locales/ja/messages.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1,5 @@
{
"extensionDescription": {
"message": "Gebruik ChatGPT, Google Gemini, Claude of Ollama om uw emails te verbeteren."
}
}

View file

@ -1,6 +1,6 @@
{
"extensionDescription": {
"message": "Używaj ChatGPT, Goolge Gemini, Anthropic lub Ollama do ulepszania swoich e-maili!",
"message": "Używaj ChatGPT, Goolge Gemini, Claude lub Ollama do ulepszania swoich e-maili!",
"description": "Description of the extension."
},
"menu_title": {
@ -24,9 +24,6 @@
"prompt_classify": {
"message": "Klasyfikuj"
},
"prompt_summarize_this": {
"message": "Podsumuj to"
},
"prompt_translate_this": {
"message": "Przetłumacz to"
},
@ -327,9 +324,6 @@
"chagpt_api_send_button": {
"message": "Używając modelu"
},
"chagpt_api_connecting": {
"message": "Próba połączenia z OpenAI ChatGPT przy użyciu podanego klucza API"
},
"Debug": {
"message": "Debugowanie"
},
@ -363,12 +357,6 @@
"ollama_empty_model": {
"message": "Nie wybrałeś modelu dla API Ollama. Proszę wybierz jeden na stronie opcji."
},
"ollama_api_connecting": {
"message": "Próba połączenia z lokalnym serwerem Ollama używając hosta"
},
"andModel": {
"message": "i modelu"
},
"error_connection_interrupted": {
"message": "Połączenie z serwerem zostało nieoczekiwanie przerwane"
},
@ -399,9 +387,6 @@
"OpenAIComp_empty_model": {
"message": "Nie wybrałeś modelu dla API kompatybilnego z OpenAI. Proszę wybierz jeden na stronie opcji."
},
"OpenAIComp_api_connecting": {
"message": "Próba połączenia z lokalnym serwerem API kompatybilnym z OpenAI używając hosta"
},
"OpenAIComp_api_request_failed": {
"message": "Zapytanie do API kompatybilnego z OpenAI nie powiodło się"
},
@ -423,12 +408,6 @@
"prefs_OptionText_dynamic_menu_force_enter_info": {
"message": "Jeśli zaznaczone, użycie skrótu klawiszowego CTRL+ALT+A automatycznie wyśle zaznaczone polecenie z menu. W przeciwnym razie nazwa polecenia zostanie wyświetlona użytkownikowi, wymagając kolejnego naciśnięcia klawisza Enter, aby je wysłać."
},
"prefs_OptionText_dynamic_menu_order_alphabet": {
"message": "Menu: sortuj alfabetycznie"
},
"prefs_OptionText_dynamic_menu_order_alphabet_info": {
"message": "Jeśli zaznaczone, polecenia w menu będą uporządkowane alfabetycznie."
},
"prefs_OptionText_chatgpt_win_dims_info": {
"message": "Ustaw na 0, jeśli nie chcesz określać rozmiaru okna."
},
@ -498,9 +477,6 @@
"chatgpt_btn_model": {
"message": "Użyj bieżącego modelu"
},
"SendingPrompt": {
"message": "Wysyłanie polecenia..."
},
"AllowedValues": {
"message": "Dozwolone wartości"
},
@ -516,9 +492,6 @@
"prefs_OptionText_owl_warning": {
"message": "Wygląda na to, że przynajmniej jedno z Twoich kont używa dodatku Owl for Exchange. Istnieje znany problem między Thunderbirdem a Owl, który jest obecnie rozwiązywany. Na ten moment możesz używać ThunderAI podczas pisania e-maili, ale nie podczas ich czytania."
},
"prefs_OptionText_chatgpt_web_model_tooltip": {
"message": "Kliknij na wartość, aby ją ustawić."
},
"prompt_reply_full_text": {
"message": "Odpowiedz na poniższy e-mail. Odpowiedz wyłącznie wymaganym tekstem, bez dodatkowych komentarzy ani innego tekstu."
},
@ -543,11 +516,8 @@
"prompt_classify_full_text": {
"message": "Sklasyfikuj poniższy tekst pod względem uprzejmości, serdeczności, formalności, stanowczości, obraźliwości, podając procent dla każdej kategorii. Odpowiedz wyłącznie kategorią i wynikiem, bez dodatkowych komentarzy ani innego tekstu."
},
"prompt_summarize_this_full_text": {
"message": "Podsumuj poniższy e-mail w formie listy punktowanej."
},
"prompt_translate_this_full_text": {
"message": "Przetłumacz poniższy e-mail na"
"message": "Przetłumacz poniższą wiadomość e-mail na język {%thunderai_translate_lang%}.\n\nZasady:\n- Przetłumacz zarówno temat, jak i treść wiadomości.\n- Zwróć wynik jako obiekt JSON z trzema polami: \"subject\", \"body\" i \"status\".\n- Jeśli tłumaczenie zostało wykonane, status wynosi 1.\n- Jeśli wiadomość e-mail jest napisana w jednym z tych języków \"{%thunderai_translate_exclude_lang%}\" lub w języku {%thunderai_translate_lang%}, zwróć pusty ciąg znaków dla treści i tematu oraz ustaw status na -1.\n- Nie dodawaj wyjaśnień, notatek ani żadnego tekstu poza formatem JSON.\n\nTemat wiadomości: {%mail_subject%}\n\nTreść wiadomości: {%mail_html_body%}\n\nWygeneruj odpowiedź wyłącznie w formacie JSON. Wynikiem powinien być tylko obiekt JSON. Oto przykład formatu JSON, którego należy użyć:\n{\n\"subject\": \"subject translation\",\n\"body\": \"body translation\",\n\"status\": \"status result\"\n}"
},
"prompt_this_full_text": {
"message": "Odpowiedz wyłącznie wymaganym tekstem, bez dodatkowych komentarzy ani innego tekstu."
@ -672,9 +642,6 @@
"google_gemini_api_request_failed": {
"message": "Połączenie do interfejsu API Google Gemini nie powiodło się"
},
"google_gemini_api_connecting": {
"message": "Próba połączenia z Google Gemini przy użyciu dostarczonego klucza API"
},
"google_gemini_empty_apikey": {
"message": "Nie dodałeś klucza API dla API Google Gemini. Wstaw go na stronie opcji."
},
@ -703,7 +670,7 @@
"message": "Dodaj nowe wydarzenie w kalendarzu"
},
"prompt_get_calendar_event_full_text": {
"message": "Wyodrębnij wszystkie istotne szczegóły wymagane do wygenerowania wydarzenia w kalendarzu z poniższego tekstu. Wyodrębnione informacje powinny obejmować:\n- Tytuł wydarzenia\n- Datę i godzinę rozpoczęcia (w tym strefę czasową, jeśli została określona)\n- Datę i godzinę zakończenia (w tym strefę czasową, jeśli została określona)\n- Cały dzień (jeśli jest podany)\n- Uczestnicy\nUpewnij się, że dane są sformatowane w sposób jasny i spójny, tak aby można go bezpośrednio wykorzystać do utworzenia wydarzenia w kalendarzu.\nJeśli istnieją odniesienia do czasu względnego, pamiętaj, że data i godzina wysłania wiadomości e-mail to „{%mail_datetime%}”. Oblicz datę i godzinę rozpoczęcia na podstawie tego odniesienia. Jeśli obliczona data i godzina rozpoczęcia są wcześniejsze niż „{%current_datetime%}”, oblicz ponownie datę i godzinę rozpoczęcia, stosując jako podstawę „{%current_datetime%}”.\nJeśli czas trwania nie jest określony, ustaw go na jedną godzinę.\nOto uczestnicy: {%author%}, {%recipients%}, {%cc_list%}. Jeśli jest obecny, wyklucz mój adres: {%account_email_address%}.\nJeśli nie możesz uzyskać co najmniej jednej z wymaganych informacji, w odpowiedzi wpisz pusty ciąg znaków.\nWygeneruj odpowiedź tylko w formacie JSON. Nie dołączaj żadnego dodatkowego tekstu ani wyjaśnień; podaj tylko JSON. Oto format, którego należy użyć:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Tutaj podsumowanie wydarzenia w kalendarzu\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOto tekst:\"{%selected_text %}\""
"message": "Wyodrębnij wszystkie istotne szczegóły wymagane do wygenerowania wydarzenia w kalendarzu z poniższego tekstu. Wyodrębnione informacje powinny obejmować:\n- Tytuł wydarzenia\n- Datę i godzinę rozpoczęcia (w tym strefę czasową, jeśli została określona)\n- Datę i godzinę zakończenia (w tym strefę czasową, jeśli została określona)\n- Cały dzień (jeśli jest podany)\n- Uczestnicy\nUpewnij się, że dane są sformatowane w sposób jasny i spójny, tak aby można go bezpośrednio wykorzystać do utworzenia wydarzenia w kalendarzu.\nJeśli istnieją odniesienia do czasu względnego, pamiętaj, że data i godzina wysłania wiadomości e-mail to „{%mail_datetime%}”. Oblicz datę i godzinę rozpoczęcia na podstawie tego odniesienia. Jeśli obliczona data i godzina rozpoczęcia są wcześniejsze niż „{%current_datetime%}”, oblicz ponownie datę i godzinę rozpoczęcia, stosując jako podstawę „{%current_datetime%}”.\nJeśli wydarzenie jest całodniowe, data zakończenia (endDate) musi przypadać na dzień po dacie rozpoczęcia (startDate), a godzina musi być ustawiona na \"T000000\".\nJeśli czas trwania nie jest określony, ustaw go na jedną godzinę.\nOto uczestnicy: {%author%}, {%recipients%}, {%cc_list%}. Jeśli jest obecny, wyklucz mój adres: {%account_email_address%}.\nJeśli nie możesz uzyskać co najmniej jednej z wymaganych informacji, w odpowiedzi wpisz pusty ciąg znaków.\nWygeneruj odpowiedź tylko w formacie JSON. Nie dołączaj żadnego dodatkowego tekstu ani wyjaśnień; podaj tylko JSON. Oto format, którego należy użyć:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Tutaj podsumowanie wydarzenia w kalendarzu\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOto tekst:\"{%mail_text_body_or_selected%}\""
},
"prefs_OptionText_get_calendar_event": {
"message": "Dodaj nowe wydarzenie w kalendarzu z zaznaczonego tekstu"
@ -771,7 +738,7 @@
"Spam_Value": {
"message": "Wartość spamu"
},
"thunderai_def_lang": {
"placeholder_thunderai_def_lang": {
"message": "Domyślny język zgodnie z opcjami ThunderAI."
},
"prompt_spamfilter": {
@ -792,15 +759,12 @@
"Moved_to_Spam": {
"message": "Przeniesiono do spamu"
},
"spamfilter_not_moved": {
"no_string": {
"message": "Nie"
},
"prefs_OptionText_add_tags_auto_force_existing_Info": {
"message": "Jeśli zaznaczone, AI doda tylko istniejące tagi do nowo odebranych e-maili i nie utworzy nowych."
},
"sparks_not_installed": {
"message": "ThunderAI Sparks nie zainstalowany!"
},
"SpamFilter_info_default": {
"message": "Na tej stronie możesz edytować domyślny prompt używany do wykrywania e-maili spamowych."
},
@ -813,7 +777,7 @@
"prefs_OptionText_btnManageSpamFilterInfo": {
"message": "Zarządzaj ustawieniami filtra spamu"
},
"spamfilter_moved": {
"yes_string": {
"message": "Tak"
},
"prefs_OptionText_spamfilter": {
@ -847,7 +811,7 @@
"message": "Zarządzaj ustawieniami filtra spamu"
},
"prompt_spamfilter_full_text": {
"message": "Przeanalizuj poniższy e-mail i określ, czy jest to spam, czy nie. Weź pod uwagę takie czynniki jak podejrzane słowa kluczowe, nadmierny język promocyjny, wprowadzające w błąd tematy, prośby o podanie danych osobowych i nietypowe adresy nadawców.\nPodaj wartość od 0 (nie spam) do 100 (spam) oraz wyjaśnienie nie dłuższe niż 10 słów.\nW przypadku braku danych wiadomości ustaw wartość na 0 (nie spam) i podaj powód.\nWygeneruj odpowiedź tylko w formacie JSON. Nie dodawaj żadnego dodatkowego tekstu ani wyjaśnień; podaj tylko JSON. Oto format, który należy użyć:\n{\n\"spamValue\": <liczba całkowita od 0 do 100>,\n\"explanation\": \"Krótkie wyjaśnienie twojego rozumowania\"\n}\nOto informacje o e-mailu:\nNadawca: \"{%author%}\"\nTemat: \"{%mail_subject%}\"\nTreść HTML: \"{%mail_html_body%}\""
"message": "Przeanalizuj poniższy e-mail i określ, czy jest to spam, czy nie. Weź pod uwagę takie czynniki jak podejrzane słowa kluczowe, nadmierny język promocyjny, wprowadzające w błąd tematy, prośby o podanie danych osobowych i nietypowe adresy nadawców.\nPodaj wartość od 0 (nie spam) do 100 (spam) oraz wyjaśnienie nie dłuższe niż 10 słów.\nW przypadku braku danych wiadomości ustaw wartość na 0 (nie spam) i podaj powód.\nWygeneruj odpowiedź tylko w formacie JSON. Nie dodawaj żadnego dodatkowego tekstu ani wyjaśnień; podaj tylko JSON. Oto format, który należy użyć:\n{\n\"explanation\": \"Krótkie wyjaśnienie twojego rozumowania\",\n\"spamValue\": <liczba całkowita od 0 do 100>\n}\nOto informacje o e-mailu:\nNadawca: \"{%author%}\"\nTemat: \"{%mail_subject%}\"\nTreść HTML: \"{%mail_html_body%}\""
},
"prefs_OptionText_spamfilter_threshold_Info": {
"message": "Jeśli wartość zwrócona przez AI przekroczy ten próg, e-mail zostanie przeniesiony do folderu spamu."
@ -858,9 +822,6 @@
"spamfilter_no_reports": {
"message": "Nie przeskanowano jeszcze żadnych wiadomości pod kątem spamu. Tutaj znajdziesz listę ostatnich 100 raportów o spamie tylko dla bieżącej sesji."
},
"context_menu_mzta-add-tags": {
"message": "Dodaj tagi"
},
"customPrompts_form_label_use_diff_viewer_title": {
"message": "Widok zmian może zostać wybrany, kiedy wybrana akcja to \"Tekst zastępczy\"."
},
@ -874,7 +835,7 @@
"message": "By używać wydarzeń w kalendarzu prosimy zainstalować zaktualizowaną wersję dodatku ThunderAI Sparks."
},
"customPrompts_form_label_use_diff_viewer": {
"message": "Włącz widok zmian"
"message": "Włącz podgląd zmian"
},
"placeholder_folder_name": {
"message": "Nazwa folderu"
@ -891,9 +852,6 @@
"prefs_OptionText_calendar_enforce_timezone": {
"message": "Wymuś konkretną strefę czasową"
},
"context_menu_mzta-spamfilter": {
"message": "Analizuj pod kątem spamu"
},
"placeholder_account_email_address": {
"message": "Adres email konta"
},
@ -905,5 +863,8 @@
},
"placeholder_mail_quoted_text": {
"message": "Zacytowany tekst w treści maila"
},
"placeholder_selected_html": {
"message": "Zaznaczony HTML"
}
}

View file

@ -1,6 +1,6 @@
{
"extensionDescription": {
"message": "Use o ChatGPT, Goolge Gemini, Anthropic ou o Ollama para aprimorar seus e-mails!",
"message": "Use o ChatGPT, Goolge Gemini, Claude ou o Ollama para aprimorar seus e-mails!",
"description": "Description of the extension."
},
"menu_title": {
@ -24,9 +24,6 @@
"prompt_classify": {
"message": "Classificar"
},
"prompt_summarize_this": {
"message": "Resuma isso"
},
"prompt_translate_this": {
"message": "Traduza isso"
},
@ -327,9 +324,6 @@
"chagpt_api_send_button": {
"message": "Usando modelo"
},
"chagpt_api_connecting": {
"message": "Tentando conectar ao OpenAI ChatGPT usando a chave de API fornecida"
},
"Debug": {
"message": "Depurar"
},
@ -363,12 +357,6 @@
"ollama_empty_model": {
"message": "Você não escolheu um modelo para a API do Ollama. Por favor, escolha um na página de opções."
},
"ollama_api_connecting": {
"message": "Tentando conectar ao servidor local do Ollama usando o host"
},
"andModel": {
"message": "e modelo"
},
"error_connection_interrupted": {
"message": "A conexão com o servidor foi interrompida inesperadamente"
},
@ -399,9 +387,6 @@
"OpenAIComp_empty_model": {
"message": "Você não escolheu um modelo para a API Compatível com OpenAI. Por favor, escolha um na página de opções."
},
"OpenAIComp_api_connecting": {
"message": "Tentando conectar ao Servidor Local da API Compatível com OpenAI usando o host"
},
"OpenAIComp_api_request_failed": {
"message": "Solicitação da API Comp do OpenAI falhou"
},
@ -423,12 +408,6 @@
"prefs_OptionText_dynamic_menu_force_enter_info": {
"message": "Se marcado, usar o atalho de teclado CTRL+ALT+A enviará automaticamente o prompt destacado do menu. Caso contrário, o nome do prompt será exibido para o usuário, exigindo outra pressão da tecla Enter para enviá-lo."
},
"prefs_OptionText_dynamic_menu_order_alphabet": {
"message": "Menu: ordenar alfabeticamente"
},
"prefs_OptionText_dynamic_menu_order_alphabet_info": {
"message": "Se marcado, os prompts no menu serão ordenados alfabeticamente."
},
"prefs_OptionText_chatgpt_win_dims_info": {
"message": "Defina como 0 se você não quiser especificar o tamanho da janela."
},
@ -498,9 +477,6 @@
"chatgpt_btn_model": {
"message": "Usar o modelo atual"
},
"SendingPrompt": {
"message": "Enviando prompt..."
},
"AllowedValues": {
"message": "Valores permitidos"
},
@ -516,9 +492,6 @@
"prefs_OptionText_owl_warning": {
"message": "Parece que pelo menos uma das suas contas está usando o complemento Coruja para Exchange. Existe um problema conhecido entre Thunderbird e Coruja, que está sendo resolvido no momento. Por enquanto, você pode usar o ThunderAI ao redigir e-mails, mas não ao lê-los."
},
"prefs_OptionText_chatgpt_web_model_tooltip": {
"message": "Clique em um valor para defini-lo."
},
"prompt_reply_full_text": {
"message": "Responda ao e-mail a seguir. Responda apenas com o texto necessário e sem comentários adicionais ou outros textos."
},
@ -543,11 +516,8 @@
"prompt_classify_full_text": {
"message": "Classifique o texto a seguir em termos de Educação, Calor, Formalidade, Assertividade e Ofensividade, atribuindo uma porcentagem para cada categoria. Responda apenas com as categorias e as pontuações, sem comentários adicionais ou outros textos."
},
"prompt_summarize_this_full_text": {
"message": "Resuma o e-mail a seguir em uma lista de tópicos."
},
"prompt_translate_this_full_text": {
"message": "Traduza o e-mail a seguir para"
"message": "Traduza o e-mail abaixo para o idioma {%thunderai_translate_lang%}.\n\nRegras:\n- Traduza tanto o assunto quanto o corpo do e-mail.\n- Retorne o resultado como um objeto JSON com três campos: \"subject\", \"body\" e \"status\".\n- Se a tradução for realizada, o status é igual a 1.\n- Se o e-mail estiver escrito em um destes idiomas \"{%thunderai_translate_exclude_lang%}\" ou no idioma {%thunderai_translate_lang%}, retorne uma string vazia para o corpo e o assunto e defina o status como -1.\n- Não adicione explicações, notas ou qualquer texto fora do JSON.\n\nAssunto do e-mail: {%mail_subject%}\n\nCorpo do e-mail: {%mail_html_body%}\n\nGere uma resposta apenas em formato JSON. A saída deve ser apenas um objeto JSON. Aqui está um exemplo do formato JSON a ser usado:\n{\n\"subject\": \"subject translation\",\n\"body\": \"body translation\",\n\"status\": \"status result\"\n}"
},
"prompt_this_full_text": {
"message": "Responda apenas com o texto necessário e sem comentários adicionais ou outros textos."
@ -562,7 +532,7 @@
"message": "Adicione tags a este e-mail"
},
"prompt_add_tags_full_text": {
"message": "Analise o seguinte texto de e-mail e gere um array JSON de tags que resumam seu conteúdo. Use temas, tópicos principais e descritores relevantes como tags. Certifique-se de que as tags sejam concisas e pertinentes ao conteúdo do e-mail.\nTexto do e-mail: {%mail_text_body%}\nConsidere os seguintes detalhes como contexto:\n- Remetente: {%author%}\n- Destinatários: {%recipients%}\n- Lista CC: {%cc_list%}\n- Assunto do e-mail: {%mail_subject%}\nBaseie-se no texto do e-mail e no contexto para gerar as tags, ignorando informações desnecessárias ou detalhes triviais.\nGere uma resposta somente no formato JSON. A saída deve ser apenas um array JSON de tags, sem nenhum comentário ou texto adicional. Aqui está um exemplo do formato JSON a ser usado:\n{\n'tags': ['tag1', 'tag2', 'tag3', 'tag4', 'tag5']\n}"
"message": "Analise o seguinte texto de e-mail e gere um array JSON de tags que resumam seu conteúdo. Use temas, tópicos principais e descritores relevantes como tags. Certifique-se de que as tags sejam concisas e pertinentes ao conteúdo do e-mail.\nTexto do e-mail: {%mail_text_body%}\nConsidere os seguintes detalhes como contexto:\n- Remetente: {%author%}\n- Destinatários: {%recipients%}\n- Lista CC: {%cc_list%}\n- Assunto do e-mail: {%mail_subject%}\nBaseie-se no texto do e-mail e no contexto para gerar as tags, ignorando informações desnecessárias ou detalhes triviais.\nGere uma resposta somente no formato JSON. A saída deve ser apenas um array JSON de tags, sem nenhum comentário ou texto adicional. Aqui está um exemplo do formato JSON a ser usado:\n{\n\"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]\n}"
},
"placeholder_tags_current_email": {
"message": "Tags do e-mail"
@ -681,9 +651,6 @@
"google_gemini_api_request_failed": {
"message": "A solicitação para a API Google Gemini falhou"
},
"google_gemini_api_connecting": {
"message": "Tentando conectar ao Google Gemini usando a chave API fornecida"
},
"google_gemini_empty_apikey": {
"message": "Você não adicionou uma chave API para a API Google Gemini. Por favor, insira uma na página de opções."
},
@ -712,7 +679,7 @@
"message": "Adicionar um novo evento ao calendário"
},
"prompt_get_calendar_event_full_text": {
"message": "Extraia todos os detalhes relevantes necessários para gerar um evento de calendário a partir do texto a seguir. As informações extraídas devem incluir:\n- Título do evento\n- Data e hora de início (incluindo fuso horário, se especificado)\n- Data e hora de término (incluindo fuso horário, se especificado)\n- Dia inteiro (se mencionado)\n- Participantes\nCertifique-se de que os dados estejam formatados de maneira clara e consistente para que possam ser usados diretamente para criar um evento de calendário.\nSe houver referências de tempo relativas, considere que a data e a hora do e-mail são \"{%mail_datetime%}\". Calcule a data e a hora de início com base nessa referência. Se a data e a hora de início calculadas forem anteriores a \"{%current_datetime%}\", recalcule a data e a hora de início usando \"{%current_datetime%}\" como base.\nSe a duração não for especificada, defina-a como uma hora.\nEstes são os participantes: {%author%}, {%recipients%}, {%cc_list%}. Se estiver presente, exclua meu endereço: {%account_email_address%}.\nSe você não conseguir obter uma ou mais informações necessárias, responda com uma string vazia.\nGere uma resposta apenas no formato JSON. Não inclua texto ou explicações adicionais; forneça apenas o JSON. Aqui está o formato a ser usado:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Resumo do evento do calendário aqui\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nAqui está o texto: \"{%selected_text%}\""
"message": "Extraia todos os detalhes relevantes necessários para gerar um evento de calendário a partir do texto a seguir. As informações extraídas devem incluir:\n- Título do evento\n- Data e hora de início (incluindo fuso horário, se especificado)\n- Data e hora de término (incluindo fuso horário, se especificado)\n- Dia inteiro (se mencionado)\n- Participantes\nCertifique-se de que os dados estejam formatados de maneira clara e consistente para que possam ser usados diretamente para criar um evento de calendário.\nSe houver referências de tempo relativas, considere que a data e a hora do e-mail são \"{%mail_datetime%}\". Calcule a data e a hora de início com base nessa referência. Se a data e a hora de início calculadas forem anteriores a \"{%current_datetime%}\", recalcule a data e a hora de início usando \"{%current_datetime%}\" como base.\nSe a duração não for especificada, defina-a como uma hora.\nEstes são os participantes: {%author%}, {%recipients%}, {%cc_list%}. Se estiver presente, exclua meu endereço: {%account_email_address%}.\nSe o evento for de dia inteiro, o campo endDate deve ser o dia seguinte ao startDate com o horário definido como \"T000000\".\nSe você não conseguir obter uma ou mais informações necessárias, responda com uma string vazia.\nGere uma resposta apenas no formato JSON. Não inclua texto ou explicações adicionais; forneça apenas o JSON. Aqui está o formato a ser usado:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Resumo do evento do calendário aqui\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nAqui está o texto: \"{%mail_text_body_or_selected%}\""
},
"prefs_OptionText_get_calendar_event": {
"message": "Adicionar um novo evento ao calendário a partir do texto selecionado"
@ -795,12 +762,9 @@
"Moved_to_Spam": {
"message": "Movido para spam"
},
"spamfilter_not_moved": {
"no_string": {
"message": "Não"
},
"sparks_not_installed": {
"message": "ThunderAI Sparks não instalado!"
},
"prefs_OptionText_btnManageSpamFilterInfo": {
"message": "Gerenciar configurações do filtro de spam"
},
@ -810,7 +774,7 @@
"prefs_OptionText_spamfilter_Info": {
"message": "Se marcado, o ThunderAI moverá automaticamente e-mails de spam para a pasta de spam."
},
"spamfilter_moved": {
"yes_string": {
"message": "Sim"
},
"SpamReport_Title": {
@ -832,7 +796,7 @@
"message": "Filtro de spam automático"
},
"prompt_spamfilter_full_text": {
"message": "Analise o seguinte e-mail e determine se é spam ou não. Considere fatores como palavras-chave suspeitas, linguagem promocional excessiva, linhas de assunto enganosas, solicitações de informações pessoais e endereços de remetentes incomuns.\nForneça um valor de 0 (não é spam) a 100 (spam) e uma explicação de no máximo 10 palavras.\nEm caso de ausência de dados da mensagem, defina o valor como 0 (não é spam) e informe o motivo.\nGere uma resposta apenas no formato JSON. Não inclua nenhum texto ou explicação adicional; forneça apenas o JSON. Aqui está o formato a ser usado:\n{\n\"spamValue\": <inteiro de 0 a 100>,\n\"explanation\": \"Breve explicação do seu raciocínio\"\n}\nAqui estão as informações do e-mail:\nRemetente: \"{%author%}\"\nAssunto: \"{%mail_subject%}\"\nCorpo HTML: \"{%mail_html_body%}\""
"message": "Analise o seguinte e-mail e determine se é spam ou não. Considere fatores como palavras-chave suspeitas, linguagem promocional excessiva, linhas de assunto enganosas, solicitações de informações pessoais e endereços de remetentes incomuns.\nForneça um valor de 0 (não é spam) a 100 (spam) e uma explicação de no máximo 10 palavras.\nEm caso de ausência de dados da mensagem, defina o valor como 0 (não é spam) e informe o motivo.\nGere uma resposta apenas no formato JSON. Não inclua nenhum texto ou explicação adicional; forneça apenas o JSON. Aqui está o formato a ser usado:\n{\n\"explanation\": \"Breve explicação do seu raciocínio\",\n\"spamValue\": <inteiro de 0 a 100>\n}\nAqui estão as informações do e-mail:\nRemetente: \"{%author%}\"\nAssunto: \"{%mail_subject%}\"\nCorpo HTML: \"{%mail_html_body%}\""
},
"prefs_OptionText_spamfilter_threshold_Info": {
"message": "Se o valor retornado pela IA estiver acima deste limite, o e-mail será movido para a pasta de spam."
@ -840,7 +804,7 @@
"prefs_OptionText_add_tags_auto_only_inbox_Info": {
"message": "Se marcado, a IA adicionará tags apenas aos e-mails recebidos na pasta da caixa de entrada."
},
"thunderai_def_lang": {
"placeholder_thunderai_def_lang": {
"message": "Idioma padrão conforme definido nas opções do ThunderAI."
},
"placeholder_thunderai_def_sign": {

173
_locales/pt/messages.json Normal file
View file

@ -0,0 +1,173 @@
{
"prompt_lang": {
"message": "Responder em"
},
"prompt_selection_needed": {
"message": "Para avançar tens que selecionar texto!"
},
"customPrompts_form_label_need_custom_text": {
"message": "Pedir texto adicional"
},
"customPrompts_form_label_use_diff_viewer_title": {
"message": "O visualizador de comparação de texto pode ser selecionado quando a ação escolhida é \"Substituir texto\"."
},
"chatgpt_win_job_completed": {
"message": "Concluído!"
},
"chatgpt_win_job_completed_select": {
"message": "Seleciona o texto que queres usar e carrega no botão."
},
"prompt_reply_advanced": {
"message": "Responder a esta sequência"
},
"more_info_string": {
"message": "Mais informação"
},
"menu_title": {
"message": "IA"
},
"prompt_classify": {
"message": "Classificar"
},
"customPrompts_add_to_menu_always": {
"message": "Sempre"
},
"prompt_reply": {
"message": "Responder a este email"
},
"prompt_rewrite_polite": {
"message": "Rescrever educadamente"
},
"prompt_rewrite_formal": {
"message": "Rescrever formalmente"
},
"prompt_translate_this": {
"message": "Traduzir isto"
},
"customPrompts_reindexing_list": {
"message": "A redefinir os índices da lista..."
},
"customPrompts_reloading_menus": {
"message": "A recarregar menus..."
},
"customPrompts_form_label_ID": {
"message": "ID"
},
"customPrompts_form_label_ID_rules": {
"message": "Deve ser único, letra minúscula e sem espaços"
},
"customPrompts_form_label_Action": {
"message": "Ação"
},
"customPrompts_form_label_need_selected": {
"message": "Necessário selecionar texto"
},
"customPrompts_form_label_need_signature": {
"message": "Adicionar sempre assinatura"
},
"customPrompts_form_label_enabled": {
"message": "Ativo"
},
"customPrompts_form_required_fields": {
"message": "Campos obrigatórios"
},
"customPrompts_btnEdit": {
"message": "Editar"
},
"customPrompts_btnCancel": {
"message": "Cancelar"
},
"customPrompts_btnOK": {
"message": "OK"
},
"customPrompts_btnDelete": {
"message": "Apagar"
},
"customPrompts_btnDelete_confirmText": {
"message": "Tens a certeza que queres apagar este item?"
},
"customPrompts_unsaved_changes": {
"message": "Existem alterações por guardar!"
},
"btnSaveAll_string": {
"message": "Guardar Tudo"
},
"btnNew_string": {
"message": "Adicionar Novo"
},
"customPrompts_add_to_menu": {
"message": "Adicionar ao menu"
},
"customPrompts_add_to_menu_reading": {
"message": "A ler um email"
},
"customPrompts_substitute_text": {
"message": "Substituir texto"
},
"customPrompts_managePrompts_info_default_3": {
"message": "Se estiver tudo certo, depois de importar carrega no botão \"Guardar Tudo\"."
},
"extensionDescription": {
"message": "Usa o ChatGPT, Google Gemini, Claude ou Ollama para melhorar os teus emails!"
},
"customPrompts_form_label_Name": {
"message": "Nome"
},
"customPrompts_add_to_menu_composing": {
"message": "A compor um email"
},
"customPrompts_form_label_use_diff_viewer": {
"message": "Ativar o visualizador de comparação de texto"
},
"chatgpt_win_working": {
"message": "Trabalho em curso..."
},
"customPrompts_managePrompts": {
"message": "Gerir prompts"
},
"customPrompts_managePrompts_info_default": {
"message": "Os prompts padrão não são editáveis. Podes desativá-los, copiar o texto do prompt e colá-lo num novo, para criar uma versão modificada."
},
"customPrompts_managePrompts_info_default_2": {
"message": "Podes importar e exportar prompts. Prompts existentes com o mesmo ID serão escritos por cima. Prompts com um ID novo serão adicionados."
},
"customPrompts_start_saving": {
"message": "A guardar prompts..."
},
"customPrompts_filtering_prompts": {
"message": "A filtrar prompts..."
},
"customPrompts_saving_default_prompts": {
"message": "A guardar prompts padrão..."
},
"customPrompts_saving_custom_prompts": {
"message": "A guardar prompts personalizados..."
},
"customPrompts_saved": {
"message": "Prompts guardados!"
},
"customPrompts_btnAddNewCommit": {
"message": "Adicionar o prompt"
},
"customPrompts_do_reply": {
"message": "Responder"
},
"prompt_reply_custom_command": {
"message": "Responder com o comando..."
},
"chatgpt_win_close": {
"message": "Fechar"
},
"chatgpt_win_get_answer": {
"message": "Utilize a resposta escolhida"
},
"customPrompts_close_button": {
"message": "Botão de Fechar"
},
"chatgpt_btn_retry": {
"message": "Repetir"
},
"chatgpt_win_send": {
"message": "Enviar"
}
}

230
_locales/ro/messages.json Normal file
View file

@ -0,0 +1,230 @@
{
"menu_title": {
"message": "IA"
},
"more_info_string": {
"message": "Informații"
},
"customPrompts_form_label_Action": {
"message": "Acțiune"
},
"customPrompts_form_label_need_signature": {
"message": "Adaugă întotdeauna semnatura"
},
"extensionDescription": {
"message": "Folosește ChatGPT, Google Gemini, Claude sau Ollama pentru îmbunătățirea e-mailurilor tale!"
},
"prompt_lang": {
"message": "Răspunde în"
},
"prompt_reply": {
"message": "Răspunde la acest e-mail"
},
"prompt_reply_advanced": {
"message": "Răspunde la această conversație"
},
"prompt_reply_custom_command": {
"message": "Răspunde cu instrucțiuni suplimentare..."
},
"prompt_rewrite_polite": {
"message": "Rescrie politicos"
},
"prompt_rewrite_formal": {
"message": "Rescrie formal"
},
"prompt_classify": {
"message": "Clasifica"
},
"prompt_translate_this": {
"message": "Tradu"
},
"prompt_selection_needed": {
"message": "Pentru a putea continua trebuie selectat un text!"
},
"customPrompts_managePrompts": {
"message": "Administrare prompturi"
},
"customPrompts_managePrompts_info_default": {
"message": "Prompturile predefinite nu pot fi modificate. Însă poți să le dezactivezi, să le copiezi și, în final, să creezi o nouă versiune a lor."
},
"customPrompts_form_label_ID": {
"message": "ID"
},
"msg_prompt_too_long": {
"message": "Textul pe care l-ai furnizat este pre lung. Este necesară reducerea lui."
},
"prefsDonation_2": {
"message": "Consideră o donație!"
},
"customPrompts_managePrompts_info_default_2": {
"message": "Poți importa și exporta prompturile. Prompturile existente cu același ID vor fi suprascrise. Prompturile cu ID-uri noi vor fi adăugate."
},
"customPrompts_managePrompts_info_default_3": {
"message": "Dacă totul este corect, dupa import apasă pe butonul 'Salvează Tot'."
},
"customPrompts_saved": {
"message": "Prompturile au fost salvate!"
},
"customPrompts_form_label_Name": {
"message": "Nume"
},
"customPrompts_form_label_Text": {
"message": "Traducere"
},
"customPrompts_form_label_need_selected": {
"message": "Este necesară selecția unui text"
},
"customPrompts_form_label_need_custom_text": {
"message": "Solicită text suplimentar"
},
"customPrompts_form_required_fields": {
"message": "Câmpuri necesare"
},
"customPrompts_btnCancel": {
"message": "Renunță"
},
"customPrompts_btnOK": {
"message": "OK"
},
"customPrompts_btnDelete": {
"message": "Șterge"
},
"customPrompts_btnDelete_confirmText": {
"message": "Ești sigur că dorești ștergerea acestui element?"
},
"customPrompts_unsaved_changes": {
"message": "Există schimbări nesalvate!"
},
"btnSaveAll_string": {
"message": "Salvează Tot"
},
"btnNew_string": {
"message": "Adaugă"
},
"customPrompts_btnAddNewCommit": {
"message": "Adaugă Promptul"
},
"customPrompts_add_to_menu": {
"message": "Adaugă la meniu"
},
"customPrompts_add_to_menu_always": {
"message": "Întotdeauna"
},
"customPrompts_close_button": {
"message": "Buton de închidere"
},
"customPrompts_substitute_text": {
"message": "Înlocuiește textul"
},
"chatgpt_win_job_completed": {
"message": "Finalizat!"
},
"chatgpt_win_job_completed_select": {
"message": "Selectează textul pe care vrei să-l folosești și apasă butonul."
},
"chatgpt_win_get_answer": {
"message": "Folosește răspunsul selectat"
},
"chatgpt_win_close": {
"message": "Închide"
},
"chatgpt_btn_retry": {
"message": "Reîncearcă"
},
"chatgpt_sendbutton_not_found_error": {
"message": "Apasă butonul de trimitere pentru a transmite promptul."
},
"chatgpt_win_custom_text": {
"message": "Introdu aici textul suplimentar pentru prompt."
},
"chatgpt_win_send": {
"message": "Trimite"
},
"prefs_status_page": {
"message": "starea serviciului"
},
"prefs_OptionText_chatgpt_win_text": {
"message": "Dimensiunile ferestrei de dialog IA"
},
"prefs_OptionText_chatgpt_win_height": {
"message": "Înălțime"
},
"prefs_OptionText_chatgpt_win_width": {
"message": "Lățime"
},
"prefs_OptionText_default_sign_name": {
"message": "Numele semnăturii implicite"
},
"prefs_OptionText_default_chatgpt_lang": {
"message": "Limba implicită pentru răspunsuri"
},
"prefs_OptionText_reply_all": {
"message": "Răspunde tuturor"
},
"prefs_OptionText_reply_sender": {
"message": "Răspunde expeditorului"
},
"prefs_OptionText_reply_type": {
"message": "Tipul răspunsului"
},
"prefs_OptionText_btnManagePrompts": {
"message": "Administrează prompturile"
},
"prompt_this": {
"message": "Întreabă"
},
"customPrompts_form_label_ID_rules": {
"message": "Trebuie să fie unic, cu litere mici și fără spații"
},
"customPrompts_form_label_enabled": {
"message": "Activat"
},
"customPrompts_form_label_use_diff_viewer": {
"message": "Activează compararea de text"
},
"customPrompts_form_label_use_diff_viewer_title": {
"message": "Comparatorul de text poate fi selectat când acțiunea este setată pe \"Înlocuire text\"."
},
"customPrompts_btnEdit": {
"message": "Editează"
},
"customPrompts_add_to_menu_reading": {
"message": "Citirea unui e-mail"
},
"customPrompts_add_to_menu_composing": {
"message": "Compunerea unui e-mail"
},
"customPrompts_do_reply": {
"message": "Răspunde"
},
"chatgpt_win_working": {
"message": "În lucru..."
},
"chatgpt_textarea_not_found_error": {
"message": "Se pare că pagina ChatGPT durează prea mult să se încarce. Dacă încărcarea se termină, faceți clic pe butonul din dreapta. Dacă problema persistă, vă rugăm să verificați starea serviciului."
},
"chatgpt_user_not_logged_in": {
"message": "Nu ești conectat la ChatGPT. Te rugăm să te conectezi cu datele tale de autentificare, să închizi fereastra ChatGPT și apoi să repeți acțiunea încercată. Vei rămâne conectat ulterior."
},
"chatgpt_win_model_warning": {
"message": "Din anumite motive, nu este posibil să verificăm dacă este încărcat modelul corect. Deocamdată, puteți apăsa butonul albastru pentru a continua."
},
"chatgpt_force_completion": {
"message": "închidere forțată"
},
"chatgpt_force_completion_title": {
"message": "Apăsați aici pentru a afișa butonul 'Utilizați ultimul răspuns' dacă ChatGPT a terminat treaba, dar butonul nu a apărut."
},
"prefs_OptionText_release_notes": {
"message": "Note de Lansare"
},
"prefs_OptionText_reply_type_Info": {
"message": "Acesta este tipul de răspuns implicit care va fi utilizat atunci când răspundeți la un e-mail. Puteți alege celălalt tip ulterior în fereastra de răspuns."
},
"prefsInfoTitle": {
"message": "Informații Importante"
},
"prefsInfoDesc_1": {
"message": "S-ar putea ca interfața web ChatGPT să se modifice într-un mod care să perturbe funcționarea addon-ului. Verificați pagina \"Starea serviciului\" accesibilă prin legătura din partea de jos a acestei pagini. De asemenea, rețineți că prima dată când utilizați ThunderAI, trebuie să vă conectați la ChatGPT."
}
}

View file

@ -93,10 +93,10 @@
"message": "Включить"
},
"customPrompts_form_label_use_diff_viewer": {
"message": "Включить просмотрщик различий"
"message": "Включить просмотр текстовых сравнений"
},
"customPrompts_form_label_use_diff_viewer_title": {
"message": "Просмотрщик различий можно выбрать, если установлено действие «Заменить текст»."
"message": "Средство просмотра для сравнения текста можно выбрать, если для действия установлено значение \"Заменить текст\"."
},
"customPrompts_form_required_fields": {
"message": "Обязательные поля"
@ -227,9 +227,6 @@
"prefsInfoDesc_3": {
"message": "Для использования интеграции с Ollama вам необходимо настроить локальный сервер Ollama. После запуска сервера введите его адрес в указанное поле в приложении. Для обеспечения корректной связи между ThunderAI и сервером Ollama не забудьте установить OLLAMA_ORIGINS=moz-extension://*."
},
"prompt_summarize_this": {
"message": "Подвести итоги"
},
"customPrompts_close_button": {
"message": "Кнопка «Закрыть»"
},
@ -348,12 +345,841 @@
"message": "Тип соединения"
},
"extensionDescription": {
"message": "Используй ChatGPT, Goolge Gemini, Anthropic или Ollama, чтобы улучшить качество своих электронных писем!"
"message": "Используй ChatGPT, Goolge Gemini, Claude или Ollama, чтобы улучшить качество своих электронных писем!"
},
"prefs_OptionText_do_debug_info": {
"message": "Активировать систему отладки"
},
"ChatGPT_Models": {
"message": "Модели ChatGPT"
},
"prefs_OptionText_btnManageCustomDataPH": {
"message": "Управление размещением данных"
},
"Ollama_Models_Error_fetching": {
"message": "Ошибка при попытке получить модели Ollama"
},
"API_Models_Error_NoModels": {
"message": "Модели не найдены"
},
"ollama_empty_host": {
"message": "Вы не добавили адрес хоста для API Ollama. Пожалуйста, укажите его на странице параметров."
},
"ollama_empty_model": {
"message": "Вы не выбрали модель для API Ollama. Пожалуйста, выберите ее на странице параметров."
},
"error_connection_interrupted": {
"message": "Соединение с сервером было неожиданно прервано"
},
"ollama_api_request_failed": {
"message": "Запрос API Ollama завершился неудачей"
},
"chatgpt_api_request_failed": {
"message": "Не удалось выполнить запрос API OpenAI ChatGPT"
},
"WaitingServerResponse": {
"message": "Ожидание ответа сервера"
},
"prefs_API_Host_Info": {
"message": "Что-то вроде"
},
"OpenAIComp_Models": {
"message": "Совместимые с OpenAI модели API"
},
"OpenAIComp_Models_Fetch": {
"message": "Обновление списка совместимых с OpenAI моделей API"
},
"OpenAIComp_Models_Error_fetching": {
"message": "Ошибка при попытке получить модели OpenAI Compatible API"
},
"OpenAIComp_empty_host": {
"message": "Вы не добавили адрес хоста для OpenAI Compatible API. Пожалуйста, укажите его на странице параметров."
},
"OpenAIComp_empty_model": {
"message": "Вы не выбрали модель для OpenAI Compatible API. Пожалуйста, выберите ее на странице параметров."
},
"OpenAIComp_api_request_failed": {
"message": "Запрос OpenAI Comp API завершился неудачей"
},
"prefs_OpenAIComp_ChatName": {
"message": "Имя чата"
},
"prefs_OpenAIComp_ChatName_Info": {
"message": "Это имя будет использоваться в чате ИИ."
},
"StorageSpace": {
"message": "Общее занимаемое пространство для хранения"
},
"SearchPrompt": {
"message": "Поисковые запросы"
},
"prefs_OptionText_dynamic_menu_force_enter": {
"message": "Меню: немедленная отправка запроса"
},
"prefs_OptionText_dynamic_menu_force_enter_info": {
"message": "Если флажок установлен, то при использовании сочетания клавиш CTRL+ALT+A будет автоматически отправляться выделенная подсказка из меню. В противном случае пользователю будет показано имя подсказки, и для ее отправки потребуется еще одно нажатие клавиши Enter."
},
"prefs_OptionText_chatgpt_win_dims_info": {
"message": "Установите значение 0, если вы не хотите указывать размер окна."
},
"prefs_OpenAIComp_API_Key": {
"message": "Ключ API OpenAI Comp"
},
"Optional": {
"message": "Дополнительно"
},
"OpenChatGPTTab": {
"message": "Откройте вкладку ChatGPT"
},
"OpenChatGPTTab_Info": {
"message": "В случае проблем со входом в окно ThunderAI откройте ChatGPT в новой вкладке с помощью кнопки справа, войдите в систему, затем закройте вкладку и продолжите работу с ThunderAI."
},
"OpenChatGPTTab_Info2": {
"message": "При открытии ChatGPT Web отсюда будут применены все настроенные параметры для модели, проекта и Custom GPT."
},
"placeholder_mail_text_body": {
"message": "Тело письма"
},
"placeholder_mail_html_body": {
"message": "Тело письма HTML"
},
"placeholder_mail_subject": {
"message": "Тема письма"
},
"placeholder_folder_name": {
"message": "Имя папки"
},
"placeholder_folder_path": {
"message": "Путь к папке"
},
"placeholder_selected_text": {
"message": "Выделенный текст"
},
"placeholder_selected_html": {
"message": "Выделенный HTML"
},
"placeholder_additional_text": {
"message": "Доп. текст"
},
"placeholder_junk_score": {
"message": "Ненужный балл"
},
"placeholder_recipients": {
"message": "Получатели"
},
"placeholder_cc_list": {
"message": "CC Список"
},
"placeholder_author": {
"message": "Автор"
},
"placeholder_account_email_address": {
"message": "Адрес эл. почты аккаунта"
},
"prefs_OptionText_placeholders_use_default_value": {
"message": "Местоимения: использовать значение по умолчанию"
},
"prefs_OptionText_placeholders_use_default_value_info": {
"message": "Если флажок установлен, то при отсутствии значения в поле заполняются значения по умолчанию. В противном случае заполнители останутся на месте."
},
"prefs_OptionText_max_prompt_length": {
"message": "Максимальная длина запроса"
},
"prefs_OptionText_max_prompt_length_Info": {
"message": "Это максимальное кол-во символов, которое может быть использовано в подсказке. В противном случае будет выведено сообщение об ошибке. Это значение не редактируется в веб-интерфейсе ChatGPT. Установите нулевое значение, чтобы отключить проверку."
},
"prefs_OptionText_chatgpt_web_model": {
"message": "Веб-модель ChatGPT"
},
"prefs_OptionText_chatgpt_web_model_info": {
"message": "Это модель, которая будет применяться для веб-интерфейса ChatGPT. Если модель не указана или указана неверно, ChatGPT установит на веб-странице модель по умолчанию. Эта настройка не будет работать с бесплатной учетной записью ChatGPT."
},
"prefs_OptionText_chatgpt_web_tempchat": {
"message": "Временный веб-чат ChatGPT"
},
"prefs_OptionText_chatgpt_web_tempchat_info": {
"message": "Если флажок установлен, временный чат будет использоваться в веб-интерфейсе ChatGPT."
},
"chatgpt_btn_model": {
"message": "Использовать текущую модель"
},
"AllowedValues": {
"message": "Разрешенные значения"
},
"prefs_OptionText_btnManagePrompts_infoline": {
"message": "Вы можете использовать доп. держатели данных."
},
"prefs_OptionText_openai_comp_use_v1": {
"message": "Сохраните совместимость с \"v1\""
},
"prefs_OptionText_openai_comp_use_v1_info": {
"message": "Если флажок установлен, сегмент \"v1\" в пути вызовов API будет сохранен, как и \"http://localhost:1234/v1/chat/completions\"."
},
"prefs_OptionText_openai_comp_info_remote": {
"message": "Здесь вы также можете вставить адрес удаленного сервера."
},
"prefs_OptionText_owl_warning": {
"message": "Похоже, что по крайней мере одна из ваших учетных записей использует дополнение Owl for Exchange. Существует известная проблема между Thunderbird и Owl, которая в настоящее время решается. На данный момент вы можете использовать ThunderAI при составлении писем, но не при их чтении."
},
"prompt_reply_full_text": {
"message": "Ответьте на следующее письмо. В ответе указывайте только необходимый текст, без лишних комментариев и прочего."
},
"prompt_reply_additional_text": {
"message": "Не добавляйте тему письма в ответ."
},
"reply_same_lang": {
"message": "Отвечайте на том же языке."
},
"sign_msg_as": {
"message": "Подпишите сообщение как"
},
"prompt_reply_advanced_full_text": {
"message": "Ответьте на следующее письмо \"{%selected_text%}\", учитывая, что это полный поток писем \"{%mail_html_body%}\". Отвечайте только на нужный текст, без лишних комментариев или другого текста."
},
"prompt_rewrite_full_text": {
"message": "Перепишите следующий текст, сделав его более вежливым. В ответ отправьте только переписанный текст без дополнительных комментариев или другого текста."
},
"prompt_rewrite_formal_full_text": {
"message": "Перепишите следующий текст, придав ему более формальный вид. Отправьте в ответ только переписанный текст без доп. комментариев или другого текста."
},
"prompt_classify_full_text": {
"message": "Классифицируйте следующий текст с точки зрения вежливости, теплоты, формальности, настойчивости, оскорбительности, указав процентное соотношение для каждой категории. В ответе укажите только категорию и оценку, без доп. комментариев или др. текста."
},
"prompt_translate_this_full_text": {
"message": "Переведите указанное ниже электронное письмо на язык {%thunderai_translate_lang%}.\n\nПравила:\n- Переведите и тему, и текст письма.\n- Верните результат в виде JSON-объекта с тремя полями: \"subject\", \"body\" и \"status\".\n- Если перевод выполнен, статус равен 1.\n- Если письмо написано на одном из этих языков \"{%thunderai_translate_exclude_lang%}\" или на языке {%thunderai_translate_lang%}, верните пустую строку для тела и темы и установите статус -1.\n- Не добавляйте никаких объяснений, заметок или любого текста вне JSON.\n\nТема письма: {%mail_subject%}\n\nТекст письма: {%mail_html_body%}\n\nСгенерируйте ответ только в формате JSON. На выходе должен быть только JSON-объект. Вот пример формата JSON, который необходимо использовать:\n{\n\"subject\": \"subject translation\",\n\"body\": \"body translation\",\n\"status\": \"status result\"\n}"
},
"prompt_this_full_text": {
"message": "Отвечайте только нужным текстом, без лишних комментариев и прочего."
},
"prefs_OptionText_add_tags": {
"message": "Добавить теги к письмам"
},
"prefs_OptionText_add_tags_Info": {
"message": "Если флажок установлен, в меню будет включен пункт для применения тегов к эл. письмам."
},
"prompt_add_tags": {
"message": "Добавить теги к этому письму"
},
"prompt_add_tags_full_text": {
"message": "Проанализируйте следующий текст эл. письма и создайте массив тегов JSON, которые кратко описывают его содержание. В качестве тегов используйте темы, ключевые темы и соответствующие дескрипторы. Убедитесь, что теги лаконичны и соответствуют содержанию письма.\nТекст письма: {%mail_text_body%}\nУчитывайте следующие сведения для контекста:\n- Отправитель: {%author%}\n- Получатели: {%recipients%}\n- Список CC: {%cc_list%}\n- Тема письма: {%mail_subject%}\nПожалуйста, основывайте свои теги на тексте и контексте письма, игнорируя ненужную информацию или тривиальные детали.\nГенерируйте ответ только в формате JSON. На выходе должен получиться только JSON-массив тегов без доп. комментариев и текста. Вот пример формата JSON, который необходимо использовать:\n{\n\"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]\n}"
},
"prompt_proofread_this": {
"message": "Вычитать это письмо"
},
"prompt_proofread_this_full_text": {
"message": "Вычитайте следующее письмо и исправьте все орфографические и грамматические ошибки. В ответ отправьте только исправленный текст без лишних комментариев или др. текста.\n\n\"{%mail_typed_text%}\""
},
"placeholder_tags_current_email": {
"message": "Почтовые теги"
},
"placeholder_tags_full_list": {
"message": "Существующие теги"
},
"prefs_OptionText_add_tags_maxnum": {
"message": "Максимальное кол-во тегов"
},
"prefs_OptionText_add_tags_maxnum_Info": {
"message": "Максимальное кол-во тегов, предложенных ИИ. Установите значение 0, если вы не хотите ограничивать кол-во тегов."
},
"prompt_add_tags_maxnum": {
"message": "Ограничьте кол-во тегов до"
},
"prefs_OptionText_add_tags_hide_exclusions": {
"message": "Скрыть исключенные теги"
},
"prefs_OptionText_add_tags_hide_exclusions_Info": {
"message": "Если флажок установлен, то теги, присутствующие в списке исключений, будут скрыты в диалоге подтверждения."
},
"prefs_OptionText_btnManageTagsInfo": {
"message": "Управление настройками тегов"
},
"AddTags_PageTitle": {
"message": "Управление настройками тегов"
},
"AddTags_info_default": {
"message": "На этой странице вы можете изменить стандартную подсказку, используемую для добавления тегов к письмам, и управлять списком исключений."
},
"AddTags_prompt_text_title": {
"message": "Текущий текст подсказки"
},
"AddTags_excl_list_title": {
"message": "Список исключений"
},
"AddTags_excl_list_infoline": {
"message": "Это список тегов, которые запрещено добавлять в эл. письма."
},
"save": {
"message": "Сохранить"
},
"addtags_info_additional_statements": {
"message": "Это утверждение будет добавлено в конце запроса:"
},
"reset_default": {
"message": "Сброс настроек по умолчанию"
},
"addtags_excl_list_infoline2": {
"message": "Добавьте по одному слову в строку или разделите их запятой."
},
"addtags_dialog_title": {
"message": "Добавьте теги в эл. письмо"
},
"addtags_exclude_tag": {
"message": "Исключить тег"
},
"addtags_no_tags_received": {
"message": "Никаких меток от ИИ не получено."
},
"addtags_no_valid_tags": {
"message": "После фильтрации с помощью списка исключений не найдено ни одного правильного тега."
},
"thunderai_error_title": {
"message": "Ошибка ThunderAI"
},
"thunderai_warning_title": {
"message": "Предупреждение ThunderAI"
},
"prefs_OptionText_add_tags_first_uppercase": {
"message": "Первая буква заглавная"
},
"prefs_OptionText_add_tags_first_uppercase_Info": {
"message": "Если флажок установлен, то в метке тегов будут использоваться строчные буквы, причем только первая буква будет прописной."
},
"AddTags_prompt_prefs_title": {
"message": "Параметры добавления тегов"
},
"prefs_SurveyLinkText": {
"message": "Поделитесь своими отзывами и помогите улучшить ThunderAI!"
},
"prefs_SurveyLinkText2": {
"message": "Нажмите здесь, это займет всего минуту!"
},
"prefs_OpenAIComp_ForceModel": {
"message": "Вставка модели вручную"
},
"OpenAIComp_force_model_ask": {
"message": "Вставьте сюда название модели, которую вы хотите использовать."
},
"prefs_OptionText_add_tags_force_lang": {
"message": "Принудительно использовать язык"
},
"prefs_OptionText_add_tags_force_lang_Info": {
"message": "Если флажок установлен, язык тегов будет принудительно соответствовать языку, заданному на странице параметров ThunderAI, если он указан."
},
"prompt_add_tags_force_lang": {
"message": "Теги должны быть написаны на"
},
"prefs_Connection_type_Google_Gemini_API": {
"message": "API Google Gemini"
},
"prefs_GoogleGemini_API_Key": {
"message": "Ключ API"
},
"GoogleGemini_Models": {
"message": "Модели API Google Gemini"
},
"GoogleGemini_Models_Fetch": {
"message": "Обновление списка моделей Google Gemini"
},
"GoogleGemini_Models_Error_fetching": {
"message": "Ошибка при попытке получить модели Google Gemini"
},
"google_gemini_api_request_failed": {
"message": "Запрос API Google Gemini завершился неудачей"
},
"google_gemini_empty_apikey": {
"message": "Вы не добавили ключ API для API Google Gemini. Пожалуйста, введите его на странице параметров."
},
"google_gemini_empty_model": {
"message": "Вы не выбрали модель для API Google Gemini. Пожалуйста, выберите ее на странице параметров."
},
"GoogleGemini_SystemInstruction": {
"message": "Инструкция по системе"
},
"GoogleGemini_SystemInstruction_Info": {
"message": "Когда вы задаете инструкцию системы, вы даете модели доп. контекст для понимания задачи, обеспечиваете более индивидуальные ответы и придерживаетесь конкретных рекомендаций по отправке подсказок."
},
"ChatGPT_Developer_Messages": {
"message": "Сообщения разработчиков"
},
"ChatGPT_Developer_Messages_Info": {
"message": "Когда вы задаете сообщения разработчика, вы даете модели доп. контекст для понимания задачи, предоставляете более индивидуальные ответы и придерживаетесь конкретных рекомендаций по отправке подсказок."
},
"prefs_OptionText_btnManagePrompts_infoline3": {
"message": "Вы можете использовать заполнитель {%tags_full_list%} в подсказке, чтобы перечислить доступные теги. С помощью соответствующей подсказки можно заставить выбирать теги только из списка уже существующих."
},
"placeholder_mail_typed_text": {
"message": "Набранный текст перед цитируемым телом письма"
},
"placeholder_mail_quoted_text": {
"message": "Цитируемый текст в теле письма"
},
"prompt_get_calendar_event": {
"message": "Добавьте новое событие календаря"
},
"prompt_get_calendar_event_full_text": {
"message": "Извлеките из следующего текста все необходимые сведения, необходимые для создания календарного события. Извлеченная информация должна включать:\n- Название события\n- Дата и время начала (включая часовой пояс, если он указан)\n- Дата и время окончания (включая часовой пояс, если он указан)\n- Полный день (если указано)\n- Участники\nУбедитесь, что данные отформатированы четко и последовательно, чтобы их можно было напрямую использовать для создания календарного события.\nЕсли есть относительные временные ссылки, считайте, что дата и время письма - это \"{%mail_datetime%}\". Рассчитайте дату и время начала на основе этой ссылки. Если вычисленные дата и время начала раньше, чем \"{%current_datetime%}\", пересчитайте дату и время начала, взяв за основу \"{%current_datetime%}\".\nЕсли продолжительность не указана, установите ее равной одному часу.\nК ним относятся: {%author%}, {%recipients%}, {%cc_list%}. Если присутствует, исключите мой адрес: {%account_email_address%}.\nЕсли это полнодневное событие, endDate должен быть на один день позже startDate с указанием времени \"T000000\".\nЕсли вы не можете получить одну или несколько требуемых данных, ответьте пустой строкой.\nГенерируйте ответ только в формате JSON. Не включайте никаких дополнительных текстов или пояснений; предоставляйте только JSON. Вот формат, который следует использовать:\n{\n\"startDate\": \"ГГГГММДДДХММССС\",\n\"endDate\": \"ГГГГММДДДХММССС\",\n\"summary\": \"Здесь выводится краткое описание события календаря\",\n\"forceAllDay\": false,\n\"attendees\": [участник1@example.com,участник2@example.com,участник3@example.com]\n}\nВот текст: \"{%mail_text_body_or_selected%}\""
},
"prompt_get_task": {
"message": "Добавить новую задачу"
},
"prompt_get_task_full_text": {
"message": "Извлеките из следующего текста все необходимые сведения, необходимые для составления задания. Извлеченная информация должна включать:\n- Дата и время выполнения (включая часовой пояс, если он указан)\n- краткое описание задачи\n- Начальная дата и время (включая часовой пояс, если он указан).\nУбедитесь, что данные отформатированы четко и последовательно, чтобы их можно было напрямую использовать для создания задачи.\nЕсли есть относительные временные ссылки, считайте, что дата и время письма - это \"{%mail_datetime%}\". Рассчитайте дату и время начала на основе этой ссылки. Если рассчитанные дата и время начала окажутся раньше, чем \"{%current_datetime%}\", пересчитайте дату и время начала, взяв за основу \"{%current_datetime%}\".\nЕсли вам не удалось получить одну или несколько требуемых данных, укажите в ответе пустую строку.\nГенерируйте ответ только в формате JSON. Не включайте никаких дополнительных текстов или пояснений; предоставляйте только JSON. Вот формат, который следует использовать:\n{\n\"InitialDate\": \"ГГГГММДДДХММССС\",\n\"dueDate\": \"ГГГГММДДДХММССС\",\n\"summary\": \"Резюме задачи здесь\"\n}\nЕсли информация о датах отсутствует, удалите их.\nВот текст: \"{%selected_text%}\""
},
"prefs_OptionText_get_calendar_event": {
"message": "Добавление нового события календаря из выделенного текста"
},
"prefs_OptionText_get_calendar_event_Info": {
"message": "Если флажок установлен, в меню будет включен пункт для получения информации о событиях календаря из выделенного текста."
},
"get_calendar_event_prompt_prefs_title": {
"message": "Параметры событий календаря"
},
"prefs_OptionText_get_task": {
"message": "Добавление нового задания из выделенного текста"
},
"prefs_OptionText_get_task_Info": {
"message": "Если флажок установлен, в меню будет включен пункт для получения информации о задаче из выделенного текста."
},
"get_task_prompt_prefs_title": {
"message": "Параметры задач"
},
"Select_your_timezone": {
"message": "Выберите часовой пояс"
},
"prefs_OptionText_calendar_enforce_timezone": {
"message": "Принудительное использование указанного часового пояса"
},
"prefs_OptionText_calendar_enforce_timezone_Info": {
"message": "Если флажок установлен, для событий календаря и задач будет применяться указанный часовой пояс."
},
"prefs_OptionText_btnManageCalendarEventInfo": {
"message": "Управление настройками событий календаря"
},
"GetCalendarEvent_PageTitle": {
"message": "Управление настройками событий календаря"
},
"GetCalendarEvent_info_default": {
"message": "На этой странице вы можете изменить стандартную подсказку, используемую для получения события календаря из выделенного текста."
},
"GetCalendarEvent_prompt_text_title": {
"message": "Текущий текст подсказки"
},
"prefs_OptionText_AdvancedPromptResponse_infoline2": {
"message": "Вы можете изменить запрос по своему усмотрению, но ответ, полученный от AI, должен быть в формате JSON, как указано в запросе по умолчанию!"
},
"prefs_OptionText_get_calendar_event_Sparks_not_present": {
"message": "Чтобы использовать функции событий и задач календаря, установите аддон ThunderAI Sparks."
},
"prefs_OptionText_get_calendar_event_Sparks_wrong_version": {
"message": "Чтобы использовать функции событий и задач календаря, установите обновленную версию аддона ThunderAI Sparks."
},
"GetTask_PageTitle": {
"message": "Настройки управления задачами"
},
"GetTask_info_default": {
"message": "На этой странице вы можете изменить стандартную подсказку, используемую для получения задания из выделенного текста."
},
"prefs_OptionText_btnManageTaskInfo": {
"message": "Управление настройками задач"
},
"prefs_OptionText_download_now": {
"message": "Скачайте ThunderAI Sparks прямо сейчас!"
},
"placeholder_mail_datetime": {
"message": "Дата и время отправки письма"
},
"placeholder_current_datetime": {
"message": "Текущая дата и время"
},
"calendar_getting_data_error": {
"message": "Ошибка при получении данных о событиях календаря"
},
"calendar_opening_dialog_error": {
"message": "Ошибка при открытии диалогового окна события календаря"
},
"task_getting_data_error": {
"message": "Ошибка при получении данных о задании"
},
"task_opening_dialog_error": {
"message": "Ошибка при открытии диалогового окна задачи"
},
"no_valid_data_received": {
"message": "Не получены достоверные данные от ИИ."
},
"prefs_OptionText_add_tags_auto": {
"message": "Добавляйте теги автоматически"
},
"prefs_OptionText_add_tags_auto_Info": {
"message": "Если флажок установлен, ИИ будет автоматически добавлять теги к вновь полученным сообщениям электронной почты."
},
"prefs_OptionText_add_tags_auto_Info2": {
"message": "Выберите, для какой учетной записи активировать эту функцию, в нижней части этой страницы."
},
"prefs_OptionText_add_tags_auto_force_existing": {
"message": "Принудительное использование существующих тегов"
},
"prefs_OptionText_add_tags_auto_force_existing_Info": {
"message": "Если флажок установлен, ИИ будет добавлять только существующие теги и не будет создавать новые теги."
},
"prefs_OptionText_add_tags_auto_only_inbox": {
"message": "Добавляйте теги только к входящим сообщениям эл. почты"
},
"prefs_OptionText_add_tags_auto_only_inbox_Info": {
"message": "Если флажок установлен, ИИ будет добавлять теги только к письмам, полученным в папке \"Входящие\"."
},
"placeholder_thunderai_def_sign": {
"message": "Подпись по умолчанию, определенная в опциях ThunderAI."
},
"placeholder_thunderai_def_lang": {
"message": "Язык по умолчанию, определенный в опциях ThunderAI."
},
"empty": {
"message": "Эта вставка не добавляет никакого текста, но предотвращает автоматическое добавление тела письма в конец запроса."
},
"prefs_OptionText_spamfilter": {
"message": "Автоматический спам-фильтр"
},
"prefs_OptionText_spamfilter_Info": {
"message": "Если флажок установлен, ThunderAI будет автоматически перемещать письма со спамом в папку \"Спам\"."
},
"prefs_OptionText_btnManageSpamFilterInfo": {
"message": "Управление настройками фильтра спама"
},
"SpamFilter_PageTitle": {
"message": "Управление настройками фильтра спама"
},
"SpamFilter_info_default": {
"message": "На этой странице вы можете изменить стандартный запрос, используемый для обнаружения спама в эл. почте."
},
"SpamFilter_prompt_text_title": {
"message": "Текущий текст подсказки"
},
"prompt_spamfilter": {
"message": "Обнаружение спама в эл. почте"
},
"prompt_spamfilter_full_text": {
"message": "Проанализируйте следующее письмо и определите, является ли оно спамом или нет. Учитывайте такие факторы, как подозрительные ключевые слова, излишняя рекламная лексика, вводящие в заблуждение тематические строки, запросы личной информации и необычные адреса отправителей.\nУкажите значение от 0 (не спам) до 100 (спам) и объяснение, состоящее не более чем из 10 слов.\nВ случае отсутствия данных о сообщении установите значение 0 (не спам) и укажите причину.\nГенерируйте ответ только в формате JSON. Не включайте никаких доп. текстов или объяснений; предоставляйте только JSON. Вот формат, который следует использовать:\n{\n\"explanation\": \"Краткое объяснение ваших рассуждений\",\n\"spamValue\": <целое число от 0 до 100>\n}\nЗдесь находится информация о почте:\nОтправитель: \"{%author%}\"\nТема: \"{%mail_subject%}\"\nHtml-тело: \"{%mail_html_body%}\""
},
"SpamFilter_prompt_prefs_title": {
"message": "Параметры спам-фильтра"
},
"prefs_OptionText_spamfilter_threshold": {
"message": "Порог спама"
},
"prefs_OptionText_spamfilter_threshold_Info": {
"message": "Если значение, возвращаемое ИИ, превышает этот порог, письмо будет перемещено в папку \"Спам\"."
},
"spamfilter_threshold_too_low": {
"message": "Порог спама слишком низок! Скорее всего, вы пометите слишком много писем как спам!"
},
"spamfilter_threshold_zero": {
"message": "Порог спама равен нулю! Вы будете помечать все письма как спам!"
},
"spamfilter_no_reports": {
"message": "Пока нет сообщений, проверенных на спам. Здесь вы найдете список последних 100 сообщений о спаме только для текущей сессии."
},
"SpamReport_Title": {
"message": "Отчеты спам-фильтра"
},
"Date": {
"message": "Дата"
},
"From": {
"message": "От"
},
"Subject": {
"message": "Тема"
},
"Spam_Value": {
"message": "Значение спама"
},
"Moved_to_Spam": {
"message": "Перемещено в спам"
},
"Explanation": {
"message": "Пояснение"
},
"Report_Date": {
"message": "Дата отчета"
},
"yes_string": {
"message": "Да"
},
"no_string": {
"message": "Нет"
},
"noActiveCalendar": {
"message": "Редактируемый календарь не найден!"
},
"btn_show_differences": {
"message": "Показать различия"
},
"chatgpt_win_diff_title": {
"message": "Различия между оригинальным и измененным текстом"
},
"apiwebchat_you": {
"message": "Вы"
},
"apiwebchat_info": {
"message": "Информация"
},
"apiwebchat_error": {
"message": "Ошибка"
},
"apiwebchat_use_this_answer": {
"message": "Используйте этот ответ"
},
"apiwebchat_stopping": {
"message": "Остановка"
},
"apiwebchat_receiving_data": {
"message": "Получение данных"
},
"hyprland_warning": {
"message": "Если у вас возникли проблемы с открытием окна чата AI, попробуйте установить значения высоты и ширины на 0. Эта проблема может возникнуть на linux в некоторых средах, например, при использовании Hyprland."
},
"remember_CORS": {
"message": "Помните, что вам необходимо настроить параметры CORS на сервере!"
},
"maybe_CORS_openai_comp": {
"message": "Использование OpenAI Compatible API может потребовать настройки CORS на сервере."
},
"CORS_alternative_1": {
"message": "Проблемы с настройкой CORS?"
},
"prefs_OptionText_composing_plain_text": {
"message": "Сочинение обычного текста"
},
"prefs_OptionText_composing_plain_text_Info": {
"message": "Установите этот флажок, если вы составляете эл. письма в формате обычного текста."
},
"Replace_No_Selected_Text": {
"message": "Текст не выбран, вы хотите вставить ответ ИИ в начало письма?"
},
"prefs_ollama_num_ctx": {
"message": "Количество контекстных токенов"
},
"prefs_ollama_num_ctx_Info": {
"message": "Количество контекстных токенов, используемых для API Ollama. Установите значение 0, если вы не хотите передавать его в качестве параметра серверу."
},
"ask_chatgptweb_permission_1": {
"message": "Чтобы использовать веб-интеграцию ChatGPT, необходимо предоставить необходимые права."
},
"ask_anthropic_api_permission_1": {
"message": "Чтобы использовать интеграцию с API Anthropic, необходимо предоставить необходимые права."
},
"ask_integration_permission_2_popup": {
"message": "Нажмите здесь, чтобы открыть новую вкладку и следовать инструкциям."
},
"ask_integration_permission_2": {
"message": "Нажмите здесь, чтобы продолжить."
},
"ask_integration_permission_ok": {
"message": "Разрешение получено. Вы можете нажать здесь, чтобы закрыть эту вкладку и вернуться в главное окно."
},
"AccountSelector_AutoTags": {
"message": "Выберите учетные записи, для которых включена автоматическая пометка"
},
"AccountSelector_AutoTags_infoline": {
"message": "Каждое изменение сохраняется сразу."
},
"AccountSelector_Spamfilter": {
"message": "Выберите учетные записи, в которых включен фильтр спама"
},
"prefs_OptionText_chatgpt_web_project": {
"message": "Веб-проект ChatGPT"
},
"prefs_OptionText_chatgpt_web_project_info": {
"message": "Это проект, который будет использоваться для веб-интерфейса ChatGPT."
},
"prefs_OptionText_chatgpt_web_custom_gpt": {
"message": "ChatGPT Пользовательский сайт GPT"
},
"prefs_OptionText_chatgpt_web_custom_gpt_info": {
"message": "Это пользовательский GPT, который будет применяться для веб-интерфейса ChatGPT."
},
"prefs_OptionText_chatgpt_web_custom_data_info": {
"message": "Это должно быть сделано в следующей форме:"
},
"prefs_OptionText_chatgpt_web_custom_data_info2": {
"message": "Вы можете найти правильное значение в поле URL браузера при открытии соответствующей страницы ChatGPT."
},
"customPrompts_Properties": {
"message": "Свойства"
},
"customPrompts_show_additional_info": {
"message": "Показать доп. свойства"
},
"customPrompts_hide_additional_info": {
"message": "Скрыть доп. свойства"
},
"customPrompts_show_additional_info_show": {
"message": "Доп. свойства"
},
"prefs_OptionText_CustomGPT_Warn": {
"message": "Если в параметрах или в подсказке указан проект, он отменяет настройку Custom GPT."
},
"prefs_OptionText_Project_No_temporary_chat_warn": {
"message": "Если в опциях или в подсказке указан Проект, временный чат не будет использоваться."
},
"prefs_Anthropic_API_Key": {
"message": "Ключ API Claude"
},
"prefs_Connection_type_Anthropic_API": {
"message": "Антропный(Claude) API"
},
"Anthropic_Models": {
"message": "Антропологические модели"
},
"Anthropic_Models_Fetch": {
"message": "Обновить список антропологических моделей"
},
"Anthropic_Models_Error_fetching": {
"message": "Ошибка при попытке получить антропные модели"
},
"Anthropic_Version": {
"message": "Антропная версия API"
},
"Anthropic_Version_Info": {
"message": "ОБЯЗАТЕЛЬНО. Не изменяйте это значение, если не знаете, что делаете. Доп. информация на сайте:"
},
"prefs_OptionText_anthropic_max_tokens": {
"message": "Claude максимум токенов"
},
"prefs_OptionText_anthropic_max_tokens_Info": {
"message": "Максимальное кол-во токенов, генерируемых в процессе завершения. Кол-во токенов в подсказке плюс max_tokens не может превышать длину контекста модели."
},
"anthropic_empty_apikey": {
"message": "Вы не добавили ключ API для API Claude. Пожалуйста, введите его на странице параметров."
},
"anthropic_empty_model": {
"message": "Вы не выбрали модель для Claude API. Пожалуйста, выберите ее на странице параметров."
},
"anthropic_empty_version": {
"message": "Вы не добавили строку версии для API Claude. Пожалуйста, вставьте ее на странице параметров."
},
"anthropic_api_request_failed": {
"message": "Claude API-запрос не удался"
},
"_api_connecting": {
"message": "Попытка подключения к $api_string$ с использованием следующей конфигурации...",
"placeholders": {
"api_string": {
"content": "$1"
}
}
},
"_api_connecting_model": {
"message": "Модель"
},
"_api_connecting_host": {
"message": "Хост"
},
"_api_connecting_version": {
"message": "Версия"
},
"prefs_OpenAIComp_AvailableServices": {
"message": "Доступные услуги"
},
"prefs_OpenAIComp_AvailableServices_Info": {
"message": "Выберите один из сервисов, доступных для OpenAI Compatible API, или вставьте его вручную."
},
"Custom": {
"message": "Пользовательский"
},
"OpenAIComp_Configs_ConfirmApply": {
"message": "Вы уверены, что хотите применить конфигурацию \"$config_name$\"?",
"placeholders": {
"config_name": {
"content": "$1"
}
}
},
"apiwebchat_selection_info": {
"message": "Если вы выделите часть текста, будет рассмотрена только эта часть."
},
"ChatGPT_chatgpt_api_store": {
"message": "Использование хранилища"
},
"ChatGPT_chatgpt_api_store_info": {
"message": "Если флажок установлен, ваши чаты будут сохраняться OpenAI."
},
"prefs_ollama_think": {
"message": "Включить режим размышления"
},
"prefs_ollama_think_Info": {
"message": "Если флажок установлен, Модель будет думать перед ответом. Эта опция работает только с моделями, поддерживающими функцию \"думать\"."
},
"chatgpt_win_change_reply_type": {
"message": "Нажмите, чтобы изменить тип ответа"
},
"prefs_OptionText_add_tags_exclusions_exact_match": {
"message": "Исключения - точное соответствие"
},
"prefs_OptionText_add_tags_exclusions_exact_match_Info": {
"message": "Если флажок установлен, слова из списка исключений будут точно соответствовать тегам. В противном случае они также будут совпадать, если включены в тег."
},
"customDataPH_manageDataPH": {
"message": "Управление заполнителями данных"
},
"customDataPH_manageDataPH_info_default_3": {
"message": "В автозаполнении можно также использовать стандартные заполнители данных, как и при написании пользовательских подсказок."
},
"customDataPH_manageDataPH_info_default": {
"message": "На этой странице можно определить заполнители данных, которые будут использоваться в пользовательских подсказках."
},
"customDataPH_manageDataPH_info_default_2": {
"message": "Существующие держатели данных с тем же идентификатором будут перезаписаны. Будут добавлены местоположения с новыми идентификаторами."
},
"customDataPH_ExportAll": {
"message": "Экспортируйте все размещаемые пользовательские данные"
},
"customDataPH_Import": {
"message": "Импорт новых заполнителей данных"
},
"customDataPH_form_label_Text": {
"message": "Текст для размещения данных"
},
"customDataPH_saving_custom": {
"message": "Сохранение пользовательских заполнителей данных..."
},
"customDataPH_saved": {
"message": "Сохранение пользовательских данных!"
},
"customDataPH_btnAddNewCommit": {
"message": "Добавьте заполнитель данных"
},
"importCustomDataPH_confirmText": {
"message": "Вы собираетесь импортировать новые пользовательские заполнители данных."
},
"importCustomDataPH_start_import": {
"message": "Запуск импорта пользовательских заполнителей данных..."
},
"importCustomDataPH_import_completed": {
"message": "Импорт пользовательских данных завершен! Чтобы сохранить изменения, нужно нажать кнопку \"Сохранить все\"."
},
"importCustomDataPH_invalidFile": {
"message": "Файл, который вы пытаетесь импортировать, не является действительным файлом пользовательских данных."
},
"importCustomDataPH_invalidDataPHs": {
"message": "Файл, который вы пытаетесь импортировать, не содержит корректных заполнителей пользовательских данных."
},
"customDataPH_add_to_menu": {
"message": "Возможность использования в подсказках, добавленных в меню"
},
"prompt_reply_custom_command": {
"message": "Ответьте командой"
},
"prompt_reply_custom_command_full_text": {
"message": "Ответьте на следующее письмо \"{%mail_text_body%}\". {%additional_text%}. Отвечайте только на нужный текст, без лишних комментариев или другого текста."
},
"prefs_OptionText_chatgpt_web_br_replace_info": {
"message": "Обратите внимание, что любые теги <br> в ответе ИИ будут заменены переносами строк."
},
"prefs_OpenAIComp_ClearModelsList": {
"message": "Очистить список моделей"
},
"OpenAIComp_ClearModelsList_Confirm": {
"message": "Вы уверены, что хотите очистить список моделей? Это действие не может быть отменено."
}
}

View file

@ -0,0 +1 @@
{}

1798
_locales/sv/messages.json Normal file

File diff suppressed because it is too large Load diff

20
_locales/tr/messages.json Normal file
View file

@ -0,0 +1,20 @@
{
"extensionDescription": {
"message": "E-postalarınızı geliştirmek için ChatGPT, Google Gemini, Claude veya Ollamayı kullanın!"
},
"menu_title": {
"message": "YZ"
},
"customPrompts_managePrompts_info_default": {
"message": "Varsayılan promptlar düzenlenemez. Bunları devre dışı bırakabilir, ardından prompt metnini kopyalayıp yeni bir prompta yapıştırarak düzenlenmiş bir sürüm oluşturabilirsiniz."
},
"customPrompts_managePrompts_info_default_2": {
"message": "Promptları içe ve dışa aktarabilirsiniz. Aynı kimliğe (ID) sahip mevcut istemlerin üzerine yazılır. Yeni kimliklere (ID) sahip promptlar eklenir."
},
"customPrompts_managePrompts_info_default_3": {
"message": "Her şey doğruysa, içe aktarma işleminden sonra Tümünü Kaydet düğmesine tıklayın."
},
"customPrompts_start_saving": {
"message": "Promptlar kaydediliyor…"
}
}

View file

@ -1,7 +1,4 @@
{
"prompt_summarize_this": {
"message": "总结一下这个"
},
"prompt_reply": {
"message": "回复此电子邮件"
},
@ -48,7 +45,7 @@
"message": "保存所有变动"
},
"extensionDescription": {
"message": "使用 ChatGPT、Google Gemini、Anthropic 或 Ollama 来提升你的电子邮件!"
"message": "使用 ChatGPT、Google Gemini、Claude 或 Ollama 来提升你的电子邮件!"
},
"menu_title": {
"message": "AI"
@ -107,9 +104,6 @@
"chatgpt_btn_model": {
"message": "使用当前模型"
},
"SendingPrompt": {
"message": "正在发送提示词..."
},
"AllowedValues": {
"message": "允许的值"
},
@ -134,10 +128,10 @@
"SpamReport_Title": {
"message": "垃圾邮件过滤报告"
},
"spamfilter_not_moved": {
"no_string": {
"message": "否"
},
"spamfilter_moved": {
"yes_string": {
"message": "是"
},
"prompt_rewrite_polite": {
@ -236,9 +230,6 @@
"prefs_OptionText_spamfilter_Info": {
"message": "如果选中ThunderAI将自动将垃圾邮件移至垃圾邮件文件夹。"
},
"sparks_not_installed": {
"message": "ThunderAI Sparks 未安装!"
},
"chatgpt_textarea_not_found_error": {
"message": "看起来 ChatGPT 页面加载时间太长。如果加载完成,请点击右边的按钮。如果问题仍然存在,请检查服务状态。"
},
@ -323,9 +314,6 @@
"prefs_Connection_type_OpenAI_Comp_API": {
"message": "OpenAI 兼容的 API"
},
"prefs_OptionText_dynamic_menu_order_alphabet_info": {
"message": "如果勾选此项,菜单中的提示将按字母顺序排列。"
},
"chatgpt_win_send": {
"message": "发送"
},
@ -341,9 +329,6 @@
"prefs_ChatGPT_API_Key": {
"message": "ChatGPT API 密钥"
},
"chagpt_api_connecting": {
"message": "尝试使用提供的 API 密钥连接到 OpenAI ChatGPT"
},
"prefs_OptionText_release_notes": {
"message": "发行说明"
},
@ -371,9 +356,6 @@
"OpenAIComp_empty_model": {
"message": "您尚未选择 OpenAI Compatible API 的模型。请在选项页面中选择一个。"
},
"OpenAIComp_api_connecting": {
"message": "尝试使用主机连接到 OpenAI 兼容 API 本地服务器"
},
"prefs_OpenAIComp_ChatName": {
"message": "对话名称"
},
@ -416,15 +398,9 @@
"importPrompts_invalidPrompts": {
"message": "您尝试导入的文件不包含任何有效提示词。"
},
"andModel": {
"message": "和模型"
},
"ChatGPT_Models_Error_fetching": {
"message": "尝试获取 ChatGPT 模型时出错"
},
"prefs_OptionText_dynamic_menu_order_alphabet": {
"message": "菜单:按字母顺序排列"
},
"prefsInfoDesc_2": {
"message": "要使用 ChatGPT API您需要一个 OpenAI ChatGPT API 密钥并且必须选择一个模型。"
},
@ -501,7 +477,7 @@
"message": "如果在 ThunderAI 窗口中遇到登录问题,请使用右侧的按钮在新标签页中打开 ChatGPT完成登录后关闭该标签页然后继续使用 ThunderAI。"
},
"prompt_translate_this_full_text": {
"message": "将以下电子邮件翻译成"
"message": "将以下电子邮件翻译成 {%thunderai_translate_lang%}。\n\n规则\n- 翻译主题和正文。\n- 以包含三个字段“subject”、“body”和“status”的 JSON 对象形式返回结果。\n- 如果翻译已完成,则状态等于 1。\n- 如果电子邮件是以这些语言“{%thunderai_translate_exclude_lang%}”之一或 {%thunderai_translate_lang%} 语言编写的,请为主体和主题返回空字符串,并将状态设置为 -1。\n- 请勿在 JSON 之外添加解释、注释或任何文本。\n\n邮件主题{%mail_subject%}\n\n邮件正文{%mail_html_body%}\n\n仅以 JSON 格式生成响应。输出应仅为一个 JSON 对象。以下是要使用的 JSON 格式示例:\n\n{\n\n\"subject\": \"主题翻译\",\n\"body\": \"正文翻译\",\n\"status\": \"状态结果\"\n}"
},
"prompt_add_tags": {
"message": "为这封电子邮件添加标签"
@ -569,9 +545,6 @@
"placeholder_cc_list": {
"message": "抄送列表"
},
"prefs_OptionText_chatgpt_web_model_tooltip": {
"message": "单击一个值进行设置。"
},
"prefs_OpenAIComp_ForceModel": {
"message": "手动填入模型"
},
@ -581,9 +554,6 @@
"OpenAIComp_force_model_ask": {
"message": "在此处填入您想要使用的模型名称。"
},
"ollama_api_connecting": {
"message": "尝试使用主机连接到 Ollama 本地服务器"
},
"ollama_api_request_failed": {
"message": "Ollama API 请求失败"
},
@ -626,7 +596,7 @@
"prefs_OptionText_placeholders_use_default_value": {
"message": "占位符:使用默认值"
},
"thunderai_def_lang": {
"placeholder_thunderai_def_lang": {
"message": "ThunderAI 选项中定义的默认语言。"
},
"prefs_OptionText_openai_comp_info_remote": {
@ -635,14 +605,11 @@
"thunderai_warning_title": {
"message": "ThunderAI 警告"
},
"google_gemini_api_connecting": {
"message": "尝试使用提供的 API 密钥连接到 Google Gemini"
},
"prefs_SurveyLinkText2": {
"message": "单击此处,只需一分钟!"
},
"prompt_add_tags_full_text": {
"message": "请分析以下电子邮件文本,并生成一个 JSON 数组的标签,总结其内容。请使用主题、关键话题和相关描述词作为标签。确保标签简洁且与邮件内容密切相关。\n邮件文本{%mail_text_body%}\n考虑以下细节以获取上下文\n- 发件人:{%author%}\n- 收件人:{%recipients%}\n- 抄送列表:{%cc_list%}\n- 邮件主题:{%mail_subject%}\n请仅根据邮件正文和上下文生成标签,忽略无关信息或琐碎细节。\n请仅以 JSON 格式生成回复。输出应仅包含标签的 JSON 数组,不包含任何额外注释或文本。以下是需使用的 JSON 格式示例:\n{\n\"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]\n}"
"message": "分析以下邮件正文,并生成一个总结其内容的 JSON 标签数组。使用主题、关键话题和相关描述符作为标签。确保标签简洁且与邮件内容相关。\n邮件正文{%mail_text_body%}\n考虑以下背景详情\n- 发件人:{%author%}\n- 收件人:{%recipients%}\n- 抄送列表:{%cc_list%}\n- 邮件主题:{%mail_subject%}\n请根据邮件的正文和背景信息生成标签,忽略不必要的信息或琐碎的细节。\n仅以 JSON 格式生成响应。输出应仅为标签的 JSON 数组,不含任何额外注释或文本。以下是要使用的 JSON 格式示例:\n{\n\"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]\n}"
},
"placeholder_tags_full_list": {
"message": "现有标签"
@ -650,9 +617,6 @@
"addtags_dialog_title": {
"message": "为电子邮件添加标签"
},
"prompt_summarize_this_full_text": {
"message": "将以下电子邮件总结为要点列表。"
},
"prompt_rewrite_formal_full_text": {
"message": "重写以下文字,使其更加正式。回复时只使用重写的文字,不要添加任何额外的评论或其他文字。"
},
@ -783,7 +747,7 @@
"message": "管理垃圾邮件过滤器设置"
},
"prompt_get_calendar_event_full_text": {
"message": "从以下文本中提取生成日历事件所需的所有相关细节。提取的信息应包括:\n- 事件标题\n- 开始日期和时间(如果指定时区,则包括时区)\n- 结束日期和时间(如果指定时区,则包括时区)\n- 全天事件(如果提及)\n- 参与者 \n确保数据格式清晰且一致以便可以直接用于创建日历事件。\n如果存在相对时间的引用请注意邮件的日期和时间为“{%mail_datetime%}”。基于此参考计算开始日期和时间。如果计算出的开始日期和时间早于“{%current_datetime%}”,则使用“{%current_datetime%}”作为基准重新计算开始日期和时间。\n如果未指定持续时间请将其设置为一小时。\n以下是参与者{%author%}, {%recipients%}, {%cc_list%}。如有,请排除我的地址:{%account_email_address%}。\n如果无法获取一个或多个所需信息,请以空字符串响应。\n仅以 JSON 格式生成响应。不要包含任何额外的文本或说明,仅提供 JSON。以下是使用的格式\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日历事件摘要\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\n以下是文本“{%selected_text%}”"
"message": "从以下文本中提取生成日历事件所需的所有相关细节。提取的信息应包括:\n- 事件标题\n- 开始日期和时间(如果指定时区,则包括时区)\n- 结束日期和时间(如果指定时区,则包括时区)\n- 全天事件(如果提及)\n- 参与者 \n确保数据格式清晰且一致以便可以直接用于创建日历事件。\n如果存在相对时间的引用请注意邮件的日期和时间为“{%mail_datetime%}”。基于此参考计算开始日期和时间。如果计算出的开始日期和时间早于“{%current_datetime%}”,则使用“{%current_datetime%}”作为基准重新计算开始日期和时间。\n如果未指定持续时间请将其设置为一小时。\n以下是参与者{%author%}, {%recipients%}, {%cc_list%}。如有,请排除我的地址:{%account_email_address%}。\n如果该活动为全天活动endDate 必须为 startDate 的后一天,且时间设置为 \"T000000\"。\n如果无法获取一个或多个所需信息,请以空字符串响应。\n仅以 JSON 格式生成响应。不要包含任何额外的文本或说明,仅提供 JSON。以下是使用的格式\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日历事件摘要\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\n以下是文本“{%mail_text_body_or_selected%}”"
},
"prefs_OptionText_get_calendar_event": {
"message": "从所选文本添加新日历事件"
@ -828,7 +792,7 @@
"message": "获取日历事件数据时出错"
},
"prompt_spamfilter_full_text": {
"message": "分析以下邮件并判断它是否为垃圾邮件。考虑因素包括可疑关键词、过多的宣传语言、误导性的主题行、索取个人信息的请求以及异常的发件人地址。\n提供一个从 0非垃圾邮件到 100垃圾邮件的值并附上不超过 10 个单词的解释。\n如果消息数据缺失将数值设为0非垃圾邮件并说明原因。\n仅以 JSON 格式生成响应。不要包含任何额外文本或解释;仅提供 JSON。以下是使用的格式\n{\n\"spamValue\": <0 到 100 的整数>,\n\"explanation\": \"简要说明您的判断理由\"\n}\n以下是邮件信息\n发件人“{%author%}”\n主题“{%mail_subject%}”\nHTML 正文:“{%mail_html_body%}”"
"message": "分析以下邮件并判断它是否为垃圾邮件。考虑因素包括可疑关键词、过多的宣传语言、误导性的主题行、索取个人信息的请求以及异常的发件人地址。\n提供一个从 0非垃圾邮件到 100垃圾邮件的值并附上不超过 10 个单词的解释。\n如果消息数据缺失将数值设为0非垃圾邮件并说明原因。\n仅以 JSON 格式生成响应。不要包含任何额外文本或解释;仅提供 JSON。以下是使用的格式\n{\n\"explanation\": \"简要说明您的判断理由\",\n\"spamValue\": <0 到 100 的整数>\n}\n以下是邮件信息\n发件人“{%author%}”\n主题“{%mail_subject%}”\nHTML 正文:“{%mail_html_body%}”"
},
"prefs_OptionText_spamfilter_threshold_Info": {
"message": "如果 AI 返回的值高于此阈值,电子邮件将被移至垃圾邮件文件夹。"
@ -851,29 +815,11 @@
"Report_Date": {
"message": "报告日期"
},
"context_menu_mzta-add-tags": {
"message": "添加标签"
},
"prefs_OptionText_add_tags_context_menu": {
"message": "显示“添加标签”上下文菜单项"
},
"prefs_OptionText_spamfilter_context_menu": {
"message": "显示“分析垃圾邮件”上下文菜单项"
},
"prefs_OptionText_spamfilter_context_menu_Info": {
"message": "如果选中,则在邮件列表中右键单击电子邮件时,将显示“分析垃圾邮件”上下文菜单项。"
},
"context_menu_mzta-spamfilter": {
"message": "分析垃圾邮件"
},
"prefs_OptionText_add_tags_context_menu_Info": {
"message": "如果选中,“添加标签”上下文菜单项将在消息列表中右键单击电子邮件时显示。"
},
"noActiveCalendar": {
"message": "未找到可编辑的日历!"
},
"customPrompts_form_label_use_diff_viewer": {
"message": "启用差异查看器"
"message": "启用文本差异查看器"
},
"get_calendar_event_prompt_prefs_title": {
"message": "日历事件选项"
@ -918,6 +864,248 @@
"message": "说明"
},
"customPrompts_form_label_use_diff_viewer_title": {
"message": "当操作设置为“替换文本”时,可以选择差异查看器。"
"message": "当操作设置为“替换文本”时,可以选择文本差异查看器。"
},
"prompt_reply_custom_command": {
"message": "使用附加的提示词指令..."
},
"prompt_string": {
"message": "提示词"
},
"prefs_OptionText_reply_type_Info": {
"message": "此即回复电子邮件时默认采用的回复类型。您可在后续的回信对话框中另行选择其他选项。"
},
"prefs_OptionText_btnManageCustomDataPH": {
"message": "管理您的数据占位符"
},
"OpenChatGPTTab_Info2": {
"message": "从此处打开 ChatGPT Web 版将应用已配置好的模型、项目及自定义 GPT 相关设置。"
},
"placeholder_mail_headers": {
"message": "邮件头"
},
"placeholder_selected_html": {
"message": "已选中的 HTML"
},
"webchat_save_as_summary": {
"message": "另存为摘要"
},
"prefs_storage_title": {
"message": "存储"
},
"prefs_storage_info": {
"message": "该存储用于保存每条消息的垃圾邮件分数、摘要和翻译。"
},
"prefs_storage_size": {
"message": "存储容量"
},
"prefs_storage_clear_button": {
"message": "清除存储"
},
"prefs_storage_clear_confirm": {
"message": "您确定要清除所有已存储的数据(包含:摘要、垃圾邮件报告、翻译等)吗?此操作无法撤销。"
},
"prefs_storage_clear_done": {
"message": "清除存储后显示的消息",
"placeholders": {
"count": {
"content": "$1"
}
}
},
"prefsInfoDesc_7": {
"message": "要使用 Google Gemini API您需要一个 Google Gemini API 密钥,并且必须选择一个模型。"
},
"prefsInfoDesc_8": {
"message": "要使用 Claude API您需要一个 Anthropic Claude API 密钥,并且必须选择一个模型。"
},
"placeholder_mail_text_body_or_selected": {
"message": "邮件正文或选定文本"
},
"placeholder_mail_html_body_or_selected": {
"message": "邮件正文或选定的 HTML"
},
"prefs_OptionText_chatgpt_web_load_wait_time": {
"message": "页面加载等待时间"
},
"prefs_OptionText_chatgpt_web_load_wait_time_info": {
"message": "在加载附加内容之前等待 ChatGPT 页面加载的时间(以毫秒为单位)。默认值为 1000 毫秒。如果定义了自定义 GPT 或项目,则该值将额外增加 1000 毫秒。"
},
"sign_msg_as": {
"message": "使用以下身份签名"
},
"prompt_reply_custom_command_full_text": {
"message": "请回复以下邮件 \"{%mail_text_body%}\"。{%additional_text%}。仅回复所需文本,不要包含额外的评论或其他文字。"
},
"prompt_proofread_this": {
"message": "校对这封邮件"
},
"prompt_proofread_this_full_text": {
"message": "请校对以下电子邮件,并纠正任何拼写或语法错误。仅回复更正后的文本,不要包含任何额外评论或其他文字。\n\n“{%mail_typed_text%}”"
},
"reset": {
"message": "重置"
},
"prefs_doc_title": {
"message": "文档"
},
"prefs_doc_setup_guide": {
"message": "设置指南"
},
"prefs_doc_custom_prompt_tutorial": {
"message": "自定义提示词教程"
},
"prefs_doc_open_welcome": {
"message": "打开欢迎页面"
},
"prompt_add_tags_force_lang": {
"message": "标签必须用以下方式编写:"
},
"placeholder_mail_quoted_text": {
"message": "邮件正文中的引用文本"
},
"prompt_get_calendar_event_from_clipboard": {
"message": "从剪贴板添加日历事件"
},
"clipboard_read_error": {
"message": "无法读取剪贴板。请检查权限。"
},
"clipboard_empty_error": {
"message": "剪贴板为空。请先复制一些文本。"
},
"clipboard_permission_denied": {
"message": "剪贴板权限被拒绝。请在设置中重新启用该功能以授予权限。"
},
"clipboard_permission_error": {
"message": "请求剪贴板权限时出错,请重试。"
},
"prefs_OptionText_get_calendar_event_from_clipboard": {
"message": "从剪贴板获取日历事件"
},
"prefs_OptionText_get_calendar_event_from_clipboard_Info": {
"message": "显示一个额外的菜单项,用于根据剪贴板文本内容创建日历事件。"
},
"Summarize_prompt_prefs_title": {
"message": "摘要选项"
},
"prompt_summarize": {
"message": "总结这封或这些邮件"
},
"prompt_summarize_full_text": {
"message": "请提供以下电子邮件的简明摘要。摘要应不超过 3-5 句话,并概括要点。请使用纯段落格式,不要使用项目符号、列表或 Markdown 格式。\n\n"
},
"prompt_summarize_email_template": {
"message": "邮件模板摘要"
},
"prompt_summarize_email_template_full_text": {
"message": "发件人:{%author%} \n收件人{%recipients%} \n抄送{%cc_list%} \n主题{%mail_subject%} \n日期{%mail_datetime%} \n附件 {%mail_attachments_info%} \n\n正文\n{%mail_text_body%}"
},
"prompt_summarize_email_separator": {
"message": "电子邮件分隔符"
},
"prompt_summarize_email_separator_full_text": {
"message": "\n\n----------下一封邮件----------\n\n"
},
"prompt_get_task": {
"message": "添加新任务"
},
"prompt_get_task_full_text": {
"message": "从以下文本中提取生成任务所需的所有相关详细信息。提取的信息应包括:\n- 截止日期和时间(如果指定,包括时区)\n- 任务摘要\n- 开始日期和时间(如果指定,包括时区)\n- 确保数据格式清晰且一致,以便直接用于创建任务。\n如果存在相对时间引用请认为电子邮件的日期和时间为“{%mail_datetime%}”。根据此参考计算开始日期和时间。如果计算出的开始日期和时间早于“{%current_datetime%}”,请使用“{%current_datetime%}”作为基准重新计算开始日期和时间。\n如果您无法获取一项或多项所需信息请回复空字符串。\n仅以 JSON 格式生成响应。不要包含任何额外的文本或说明;仅提供 JSON。以下是要使用的格式\n{\n\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"在此处填写任务摘要\"\n}\n如果没有关于日期的信息请将其删除。\n以下是文本“{%selected_text%}”"
},
"prefs_OptionText_get_task": {
"message": "从选定文本添加新任务"
},
"prefs_OptionText_get_task_Info": {
"message": "如果选中,则会在菜单中添加一个项目,以便从选定的文本获取任务信息。"
},
"get_task_prompt_prefs_title": {
"message": "任务选项"
},
"prefs_OptionText_Summarize_infoline2": {
"message": "您可以根据需要更改提示词,第一个字段是主提示词,第二个字段是单封邮件的模板。邮件列表将附加到主提示词中。邮件将由第三个字段中指定的间隔符分隔。"
},
"prefs_OptionText_Summarize_main_prompt": {
"message": "针对所有选定电子邮件,描述要执行的任务的主要提示:"
},
"prefs_OptionText_Summarize_email_template": {
"message": "单封邮件的模板:"
},
"prefs_OptionText_Summarize_email_separator": {
"message": "电子邮件地址之间的分隔符:"
},
"prefs_OptionText_get_calendar_event_Sparks_wrong_version": {
"message": "要使用日历事件和任务功能,请安装最新版本的 ThunderAI Sparks 插件。"
},
"GetTask_PageTitle": {
"message": "管理任务设置"
},
"GetTask_info_default": {
"message": "在此页面中,您可以修改用于从选定文本获取任务的默认提示。"
},
"prefs_OptionText_btnManageTaskInfo": {
"message": "管理任务设置"
},
"task_getting_data_error": {
"message": "获取任务数据时出错"
},
"task_opening_dialog_error": {
"message": "打开任务对话框时出错"
},
"no_valid_data_received": {
"message": "未收到来自 AI 的有效数据。"
},
"prefs_OptionText_add_tags_auto_Info2": {
"message": "请在页面底部选择要为其激活此功能的帐户。"
},
"prefs_OptionText_add_tags_auto_uselist": {
"message": "仅使用这些标签"
},
"prefs_OptionText_add_tags_auto_uselist_Info": {
"message": "如果选中此项AI 将仅添加以下列表中的标签。"
},
"prefs_OptionText_add_tags_auto_uselist_list_Info": {
"message": "列表中必须至少包含一个标签。每行添加一个标签,标签之间用逗号分隔。"
},
"prompt_add_tags_use_list": {
"message": "仅使用此逗号分隔列表中的标签"
},
"prefs_OptionText_add_tags_use_specific_integration_Info": {
"message": "如果选中此项,则无论在 ThunderAI 选项页面中选择哪个模型和 API都将使用下面指定的模型和 API 向电子邮件添加标签。"
},
"SpamFilter_skip_addresses_infoline2": {
"message": "每行添加一个电子邮件地址,或用逗号分隔。"
},
"spamfilter_skip_addresses_explanation": {
"message": "发件人已在反垃圾邮件跳过列表中。"
},
"Valid": {
"message": "有效的"
},
"hyprland_warning": {
"message": "如果您在打开 AI 聊天窗口时遇到问题,请尝试将高度和宽度值设置为 0。此问题可能在某些 Linux 环境下出现,例如在使用 Hyprland 时。"
},
"remember_CORS": {
"message": "记住,您需要在服务器上设置 CORS 设置!"
},
"maybe_CORS_openai_comp": {
"message": "使用 OpenAI 兼容 API 可能需要在服务器上设置 CORS 设置。"
},
"CORS_alternative_1": {
"message": "CORS设置有问题吗"
},
"CORS_alternative_2_new": {
"message": "点击下方按钮授予当前主机权限,以避免任何 CORS 问题。"
},
"CORS_give_host_perm": {
"message": "授予当前主机权限"
},
"CORS_localhost_warn": {
"message": "如果您使用 localhost 或 127.0.0.1,因为 AI 服务器托管在您的 PC 上,则需要 <all_urls> 权限。"
},
"prefs_OptionText_composing_plain_text": {
"message": "以纯文本编写"
},
"prefs_OptionText_composing_plain_text_Info": {
"message": "如果您以纯文本格式编写电子邮件,请选中此选项。"
}
}

View file

@ -32,9 +32,6 @@
"prompt_classify": {
"message": "分類"
},
"prompt_summarize_this": {
"message": "摘要這段"
},
"prompt_this": {
"message": "提示這段"
},
@ -284,7 +281,7 @@
"Spam_Value": {
"message": "垃圾訊息評分"
},
"spamfilter_not_moved": {
"no_string": {
"message": "否"
},
"Report_Date": {
@ -300,10 +297,10 @@
"message": "額外屬性"
},
"Anthropic_Models": {
"message": "Anthropic 模型"
"message": "Claude 模型"
},
"_api_connecting_model": {
"message": "模型$model$",
"message": "模型",
"placeholders": {
"model": {
"content": "$1"
@ -317,7 +314,7 @@
"message": "啟用思考"
},
"extensionDescription": {
"message": "使用 ChatGPT、Google Gemini、Anthropic 或 Ollama 來幫你寫好你的郵件吧!"
"message": "使用 ChatGPT、Google Gemini、Claude 或 Ollama 來幫你寫好你的郵件吧!"
},
"customPrompts_form_label_Name": {
"message": "名稱"
@ -353,7 +350,7 @@
"message": "主旨"
},
"_api_connecting_version": {
"message": "版本$api_version$",
"message": "版本",
"placeholders": {
"api_version": {
"content": "$1"
@ -387,14 +384,14 @@
"Date": {
"message": "日期"
},
"spamfilter_moved": {
"yes_string": {
"message": "是"
},
"Custom": {
"message": "自訂"
},
"prefs_Connection_type_Anthropic_API": {
"message": "Anthropic API"
"message": "Claude API"
},
"save": {
"message": "儲存"
@ -414,9 +411,6 @@
"customPrompts_ExportAll": {
"message": "匯出所有提示"
},
"prefs_OptionText_dynamic_menu_order_alphabet": {
"message": "選單:按字母排序"
},
"prefs_API_Host": {
"message": "主機位址"
},
@ -429,12 +423,6 @@
"prefs_API_Host_Info": {
"message": "類似於"
},
"SendingPrompt": {
"message": "送出提示中..."
},
"context_menu_mzta-add-tags": {
"message": "新增標籤"
},
"placeholder_mail_subject": {
"message": "郵件主旨"
},
@ -448,7 +436,7 @@
"message": "選取的文字"
},
"_api_connecting_host": {
"message": "主機$api_host$",
"message": "主機",
"placeholders": {
"api_host": {
"content": "$1"
@ -533,9 +521,6 @@
"chatgpt_api_request_failed": {
"message": "OpenAI ChatGPT API 請求失敗"
},
"WaitingServerReponse": {
"message": "等待伺服器回應"
},
"error_connection_interrupted": {
"message": "與伺服器的連線意外中斷"
},
@ -632,12 +617,6 @@
"SpamReport_Title": {
"message": "垃圾郵件過濾報告"
},
"context_menu_mzta-spamfilter": {
"message": "檢測垃圾郵件"
},
"prefs_OptionText_spamfilter_context_menu_Info": {
"message": "如果勾選,則在訊息清單中點右鍵時,會出現「分析垃圾郵件」快顯功能選單項目。"
},
"apiwebchat_use_this_answer": {
"message": "使用這個答案"
},
@ -645,13 +624,13 @@
"message": "這是將針對 ChatGPT 網頁介面強制執行的專案。"
},
"Anthropic_Models_Fetch": {
"message": "更新 Anthropic 模型列表"
"message": "更新 Claude 模型列表"
},
"prefs_Anthropic_API_Key": {
"message": "Anthropic API 金鑰"
"message": "Claude API 金鑰"
},
"anthropic_api_request_failed": {
"message": "Anthropic API 請求失敗"
"message": "Claude API 請求失敗"
},
"OpenAIComp_Configs_ConfirmApply": {
"message": "您確定要套用設定「$config_name$」嗎?",
@ -662,7 +641,7 @@
}
},
"prefs_OptionText_add_tags_exclusions_exact_match_Info": {
"message": "如果勾選中,則排除清單中的標籤將完全匹配,否則將部分匹配。"
"message": "如果勾選,排除列表中的詞語將與標籤完全匹配。否則,若詞語包含於標籤內,亦視為匹配。"
},
"prefs_OptionText_openai_comp_use_v1": {
"message": "保持“v1”相容性"
@ -677,7 +656,7 @@
"message": "回覆以下郵件。僅回覆所需內容,不要提供任何註解或其他文字。"
},
"prompt_translate_this_full_text": {
"message": "將以下電子郵件翻譯成"
"message": "將以下電子郵件翻譯成 **{%thunderai_translate_lang%}**。\n\n**規則:**\n- 同時翻譯主題Subject與正文Body。\n- 以 JSON 物件格式回傳結果,包含三個欄位:\"subject\"、\"body\" 以及 \"status\"。\n- 如果完成翻譯status 等於 1。\n- 如果郵件是以 \"{%thunderai_translate_exclude_lang%}\" 其中之一的語言或 {%thunderai_translate_lang%} 語言編寫,請將 body 和 subject 設為空字串,並將 status 設為 -1。\n- 請勿在 JSON 之外添加任何說明、備註或文字。\n\n郵件主題{%mail_subject%}\n\n郵件正文{%mail_html_body%}\n\n請僅以 JSON 格式生成回應。輸出應僅包含一個 JSON 物件。以下是要使用的 JSON 格式範例:\n{\n\"subject\": \"subject translation\",\n\"body\": \"body translation\",\n\"status\": \"status result\"\n}"
},
"prompt_rewrite_full_text": {
"message": "請重寫以下文字,使其更有禮貌。僅回覆重寫的文字,不要提供任何額外的註解或其他文字。"
@ -788,7 +767,7 @@
"message": "ThunderAI 選項中定義的預設簽章。"
},
"prefs_OptionText_add_tags_auto_force_existing": {
"message": "自動標記或快顯功能選單時強制使用現有標記"
"message": "強制使用現有標記"
},
"prefs_OptionText_add_tags_auto_Info2": {
"message": "在此頁面底部選擇要啟動此功能的帳戶。"
@ -802,9 +781,6 @@
"prefs_OptionText_spamfilter_threshold_Info": {
"message": "如果 AI 傳回的值高於此閾值,則電子郵件將被移至垃圾郵件資料夾。"
},
"prefs_OptionText_add_tags_context_menu": {
"message": "顯示「新增標籤」在快顯功能選單"
},
"remember_CORS": {
"message": "記住,您需要在伺服器上設定 CORS 設定!"
},
@ -815,7 +791,7 @@
"message": "點擊此處開啟新分頁並按照說明進行操作。"
},
"ask_anthropic_api_permission_1": {
"message": "要使用 Anthropic API 整合,您需要授予所需的權限。"
"message": "要使用 Claude API 整合,您需要授予所需的權限。"
},
"ask_integration_permission_ok": {
"message": "已授予權限。您可以按一下此處關閉此分頁並返回主視窗。"
@ -845,10 +821,10 @@
"message": "如果在選項或提示中指定了專案,則不會使用臨時聊天。"
},
"Anthropic_Models_Error_fetching": {
"message": "嘗試取得 Anthropic 模型時出錯"
"message": "嘗試取得 Claude 模型時出錯"
},
"_api_connecting": {
"message": "嘗試使用以下配置連接到 $api_string$",
"message": "嘗試使用以下配置連接到 $api_string$...",
"placeholders": {
"api_string": {
"content": "$1"
@ -856,10 +832,10 @@
}
},
"anthropic_empty_model": {
"message": "您尚未選擇 Anthropic API 的模型。請在選項頁面中選擇一個。"
"message": "您尚未選擇 Claude API 的模型。請在選項頁面中選擇一個。"
},
"anthropic_empty_version": {
"message": "您尚未新增 Anthropic API 的版本字串。請在選項頁面中輸入一個。"
"message": "您尚未新增 Claude API 的版本字串。請在選項頁面中輸入一個。"
},
"ChatGPT_chatgpt_api_store_info": {
"message": "如果勾選,您的聊天記錄將由 OpenAI 儲存。"
@ -916,7 +892,7 @@
"message": "自動新增標籤"
},
"anthropic_empty_apikey": {
"message": "您尚未新增 Anthropic API 的 API 金鑰。請在選項頁面中輸入一個。"
"message": "您尚未新增 Claude API 的 API 金鑰。請在選項頁面中輸入一個。"
},
"prefs_OpenAIComp_ForceModel": {
"message": "手動輸入模型"
@ -928,7 +904,7 @@
"message": "管理任務設定"
},
"Anthropic_Version": {
"message": "Anthropic API 版本"
"message": "Claude API 版本"
},
"prefs_OptionText_spamfilter": {
"message": "自動垃圾郵件過濾器"
@ -937,7 +913,7 @@
"message": "已移到垃圾郵件"
},
"prefs_OptionText_anthropic_max_tokens": {
"message": "Anthropic 最大 Token 數"
"message": "Claude 最大 Token 數"
},
"prefs_OpenAIComp_API_Key": {
"message": "OpenAI 相容 API 金鑰"
@ -993,9 +969,6 @@
"prompt_reply_additional_text": {
"message": "不要在回覆中加入主旨。"
},
"prompt_summarize_this_full_text": {
"message": "將以下電子郵件總結為要點清單。"
},
"prefs_OptionText_placeholders_use_default_value": {
"message": "佔位符:使用預設值"
},
@ -1005,16 +978,13 @@
"prefs_OptionText_btnManageSpamFilterInfo": {
"message": "管理垃圾郵件設定"
},
"CORS_give_allurls_perm": {
"message": "授予「所有網址」權限"
},
"prefs_ollama_num_ctx": {
"message": "情境 Token 數量"
},
"prefs_OptionText_chatgpt_web_custom_gpt": {
"message": "ChatGPT 網頁 GPT"
"message": "ChatGPT 網頁訂 GPT"
},
"thunderai_def_lang": {
"placeholder_thunderai_def_lang": {
"message": "ThunderAI 選項中定義的預設語言。"
},
"prefs_SurveyLinkText2": {
@ -1026,12 +996,6 @@
"spamfilter_threshold_zero": {
"message": "垃圾郵件閾值為零!您將把所有郵件標記為垃圾郵件!"
},
"prefs_OptionText_chatgpt_web_model_tooltip": {
"message": "點擊一個值來設定它。"
},
"prefs_OptionText_dynamic_menu_order_alphabet_info": {
"message": "如果勾選,選單中的提示將按字母順序排列。"
},
"prefs_OptionText_spamfilter_Info": {
"message": "如果勾選ThunderAI 將自動將垃圾郵件移至垃圾郵件資料夾。"
},
@ -1063,7 +1027,7 @@
"message": "垃圾郵件閾值太低!您可能會將太多郵件標記為垃圾郵件!"
},
"prefs_OptionText_add_tags_auto_force_existing_Info": {
"message": "如果勾選AI 將僅對新收到的電子郵件新增現有標籤,而不會建立新標籤。"
"message": "如果勾選AI 將僅新增現有標籤,而不會建立新標籤。"
},
"prefs_OptionText_CustomGPT_Warn": {
"message": "如果在選項或提示中指定了專案,它將覆蓋自訂 GPT 設定。"
@ -1087,7 +1051,7 @@
"message": "您尚未選擇 ChatGPT API 的模型。請在選項頁面中選擇一個。"
},
"prompt_get_calendar_event_full_text": {
"message": "從以下文字中提取所有需要生成日曆事件的相關資訊。 提取的資訊應包含:\n- 事件名稱\n- 起始日期和時間(包含時區,如果指定)\n- 結束日期和時間(包含時間區,如果指定)\n- 整天事件(如果提及\n- 參與者\n確保數據以清晰一致的方式格式化以便直接用於創建日曆事件。\n如果有相對時間參考請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。 如果計算出的起日期和時間早於「{%current_datetime%}」,則使用「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果持續時間沒有指定則設定為一小時。\n參與者{%author%}, {%recipients%}, {%cc_list%}。如果存在,請排除我的地址:{%account_email_address%}。\n如果無法獲得其中一個或多個所需的資訊,請回覆一個空字串。\n請以 JSON 格式回覆,不要包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日曆事件摘要在此\",\n\"forceAllDay\": false,\n\"attendees\": [\"attendee1@example.com \",\"attendee2@example.com \",\"attendee3@example.com \"]\n}\n這裡是文字「{%selected_text%}」"
"message": "從以下文字中提取所有需要生成日曆事件的相關資訊。 提取的資訊應包含:\n- 事件名稱\n- 起始日期和時間(包含時區,如果指定)\n- 結束日期和時間(包含時間區,如果指定)\n- 整天事件(如果提及\n- 參與者\n確保數據以清晰一致的方式格式化以便直接用於創建日曆事件。\n如果有相對時間參考請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。 如果計算出的起日期和時間早於「{%current_datetime%}」,則使用「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果持續時間沒有指定則設定為一小時。\n參與者{%author%}, {%recipients%}, {%cc_list%}。如果存在,請排除我的地址:{%account_email_address%}。\n如果該活動為全天活動endDate 必須為 startDate 的後一天,且時間設置為 \"T000000\"。\n如果無法獲得其中一個或多個所需的資訊,請回覆一個空字串。\n請以 JSON 格式回覆,不要包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日曆事件摘要在此\",\n\"forceAllDay\": false,\n\"attendees\": [\"attendee1@example.com \",\"attendee2@example.com \",\"attendee3@example.com \"]\n}\n這裡是文字「{%mail_text_body_or_selected%}」"
},
"TranslateText": {
"message": "您願意幫忙翻譯這個附加元件嗎?"
@ -1095,9 +1059,6 @@
"prompt_get_task_full_text": {
"message": "從以下文字中提取所有需要生成任務的相關資訊。 提取的資訊應包含:\n- 截止日期和時間(包括時區,如果指定)\n- 任務總結\n- 初始日期和時間(包括時區,如果指定)\n確保數據以清晰一致的方式格式化以便直接用於建立任務。\n如果有相對時間參考請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。如果計算出的起日期和時間早於「{%current_datetime%}」,則使用 「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果無法獲得其中一個或多個所需的資訊請回覆一個空字串。\n請以 JSON 格式回覆,不包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"任務總結在此\"\n}\n如果沒有日期資訊請刪除這些資訊。\n以下是文字「{%selected_text%}」"
},
"prefs_OptionText_spamfilter_context_menu": {
"message": "顯示「分析垃圾郵件」在快顯功能選單"
},
"sign_msg_as": {
"message": "簽署訊息為"
},
@ -1111,7 +1072,7 @@
"message": "ChatGPT 網頁介面可能會發生一些變化,導致附加元件無法正常運作。請查看此頁面底部連結的「服務狀態」頁面。另外,請記住,首次使用 ThunderAI 時,您需要登入 ChatGPT。"
},
"prompt_spamfilter_full_text": {
"message": "分析以下 Email 並判斷是否為垃圾郵件。 考慮因素包括可疑關鍵字、過度推銷性語言、誤導性主旨、要求個人資訊以及異常的寄件人地址。\n提供一個 0 (非垃圾郵件) 到 100 (垃圾郵件) 的分數,並提供一段不超過 10 字的說明。\n如果缺少訊息資料則設定分數為 0 (非垃圾郵件),並說明原因。\n請以 JSON 格式回覆,不包含任何額外的文字或說明,提供僅 JSON。以下是將要使用的格式\n{\n\"spamValue\": <由 0 到 100 的整數>,\n\"explanation\": \"簡短說明您的理由\"\n}\n以下是郵件資訊\n寄件人「{%author%}」\n主旨「{%mail_subject%}」\nHTML 內容:「{%mail_html_body%}」"
"message": "分析以下 Email 並判斷是否為垃圾郵件。 考慮因素包括可疑關鍵字、過度推銷性語言、誤導性主旨、要求個人資訊以及異常的寄件人地址。\n提供一個 0 (非垃圾郵件) 到 100 (垃圾郵件) 的分數,並提供一段不超過 10 字的說明。\n如果缺少訊息資料則設定分數為 0 (非垃圾郵件),並說明原因。\n請以 JSON 格式回覆,不包含任何額外的文字或說明,提供僅 JSON。以下是將要使用的格式\n{\n\"explanation\": \"簡短說明您的理由\",\n\"spamValue\": <由 0 到 100 的整數>\n}\n以下是郵件資訊\n寄件人「{%author%}」\n主旨「{%mail_subject%}」\nHTML 內容:「{%mail_html_body%}」"
},
"task_getting_data_error": {
"message": "取得取得任務資料時出錯"
@ -1137,15 +1098,9 @@
"prompt_rewrite_formal_full_text": {
"message": "請將以下文字重寫得更正式一些。僅回覆重寫的文字,不要提供任何額外的註解或其他文字。"
},
"CORS_alternative_2": {
"message": "點擊下方按鈕,授予「所有網址」權限,以避免任何 CORS 問題。"
},
"GoogleGemini_SystemInstruction_Info": {
"message": "當您設定系統指示時,您會為模型提供額外情境來理解任務,提供更客製化的回應,並遵守將要發送的提示的特定指南。"
},
"prefs_OptionText_add_tags_context_menu_Info": {
"message": "如果勾選,則右鍵單擊訊息清單中的電子郵件時將顯示「新增標籤」在快顯功能選單。"
},
"prefs_OptionText_chatgpt_web_custom_gpt_info": {
"message": "這是將針對 ChatGPT 網頁介面強制執行的自訂 GPT。"
},
@ -1159,7 +1114,7 @@
"message": "將以下文字按禮貌、熱情、正式、自信和冒犯性進行分類,並為每個類別給出百分比。僅回覆該類別並評分,不要提供任何註解或其他文字。"
},
"prompt_add_tags_full_text": {
"message": "分析以下電子郵件文字,並生成一個 JSON 陣列,總結其內容。 使用主題、關鍵話題和相關描述作為標籤。 確保標籤簡潔且與電子郵件的內容相關。 請分析以下電子郵件文字:\n{%mail_text_body%}\n考慮以下細節作為背景資訊\n- 寄件人:{%author%}\n- 收件人:{%recipients%}\n- 副本清單:{%cc_list%}\n- 電子郵件主旨:{%mail_subject%}\n請根據電子郵件的文字和背景資訊忽略不必要的資訊或瑣碎細節。\n請以 JSON 格式回覆,輸出僅為一個包含標籤的 JSON 陣列,不包含任何額外的註解或文字。 以下是一個 JSON 格式的範例:\n{\n'tags': ['tag1', 'tag2', 'tag3', 'tag4', 'tag5']\n}"
"message": "分析以下電子郵件文字,並生成一個 JSON 陣列,總結其內容。 使用主題、關鍵話題和相關描述作為標籤。 確保標籤簡潔且與電子郵件的內容相關。 請分析以下電子郵件文字:\n{%mail_text_body%}\n考慮以下細節作為背景資訊\n- 寄件人:{%author%}\n- 收件人:{%recipients%}\n- 副本清單:{%cc_list%}\n- 電子郵件主旨:{%mail_subject%}\n請根據電子郵件的文字和背景資訊忽略不必要的資訊或瑣碎細節。\n請以 JSON 格式回覆,輸出僅為一個包含標籤的 JSON 陣列,不包含任何額外的註解或文字。 以下是一個 JSON 格式的範例:\n{\n\"tags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"]\n}"
},
"prefs_OptionText_add_tags_force_lang_Info": {
"message": "如果勾選,標籤的語言會強制設定為選項頁面所定義的語言,若有指定則使用。"
@ -1175,5 +1130,71 @@
},
"WaitingServerResponse": {
"message": "等待伺服器回應"
},
"prefs_OptionText_btnManageCustomDataPH": {
"message": "管理您的資料佔位符"
},
"customDataPH_manageDataPH": {
"message": "管理資料佔位符"
},
"customDataPH_manageDataPH_info_default_3": {
"message": "您也可以使用自動完成功能的預設資料佔位符,就像撰寫自訂提示詞時一樣。"
},
"customDataPH_manageDataPH_info_default": {
"message": "在此頁面上,您可以定義自訂資料佔位符,以便在您的自訂提示詞中使用。"
},
"customDataPH_manageDataPH_info_default_2": {
"message": "具有相同 ID 的現有資料佔位符將被覆寫。具有新 ID 的佔位符將被新增。"
},
"customDataPH_ExportAll": {
"message": "匯出所有自訂資料佔位符"
},
"customDataPH_Import": {
"message": "滙入新的資料佔位符"
},
"customDataPH_form_label_Text": {
"message": "資料佔位符文字"
},
"customDataPH_saving_custom": {
"message": "儲存自訂資料佔位符..."
},
"customDataPH_saved": {
"message": "自訂資料佔位符已儲存!"
},
"customDataPH_btnAddNewCommit": {
"message": "新增資料佔位符"
},
"importCustomDataPH_confirmText": {
"message": "即將滙入新的自訂資料佔位符。"
},
"importCustomDataPH_start_import": {
"message": "開始滙入自訂資料佔位符..."
},
"importCustomDataPH_import_completed": {
"message": "自訂資料佔位符滙入完成!請點擊「儲存全部」按鈕以儲存您的變更。"
},
"importCustomDataPH_invalidFile": {
"message": "您嘗試滙入的檔案不是有效的自訂資料佔位符檔案。"
},
"importCustomDataPH_invalidDataPHs": {
"message": "您嘗試滙入的檔案未包含任何有效的自訂資料佔位符。"
},
"customDataPH_add_to_menu": {
"message": "已將可使用的內容新增至選單提示中"
},
"prompt_reply_custom_command": {
"message": "依指令回覆"
},
"prompt_reply_custom_command_full_text": {
"message": "請回覆以下電子郵件 \"{%mail_text_body%}”。{%additional_text%}。僅回覆所需內容,不要提供任何註解或其他文字。"
},
"prefs_OptionText_chatgpt_web_br_replace_info": {
"message": "請注意AI 回應中的任何 <br> 標籤將被替換為換行。"
},
"prefs_OpenAIComp_ClearModelsList": {
"message": "清除模型清單"
},
"OpenAIComp_ClearModelsList_Confirm": {
"message": "確定要清除模型清單嗎?這個動作無法復原。"
}
}

View file

@ -1,6 +1,6 @@
/*
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
* Copyright (C) 2024 - 2025 Mic (m@micz.it)
* Copyright (C) 2024 - 2026 Mic (m@micz.it)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,14 +20,18 @@
* The original code has been released under the Apache License, Version 2.0.
*/
import { prefs_default, integration_options_config } from '../options/mzta-options-default.js';
import { placeholdersUtils } from '../js/mzta-placeholders.js';
import { getAPIsInitMessageString } from '../js/mzta-utils.js';
import { getAPIsInitMessageString, convertNewlinesToBr } from '../js/mzta-utils.js';
import { loadPrompt } from '../js/mzta-prompts.js';
// Get the LLM to be used
const urlParams = new URLSearchParams(window.location.search);
const llm = urlParams.get('llm');
const call_id = urlParams.get('call_id');
const ph_def_val = urlParams.get('ph_def_val');
const prompt_id = urlParams.get('prompt_id');
const prompt_name = urlParams.get('prompt_name');
// Data received from the user
let promptData = null;
@ -43,102 +47,185 @@ const messagesArea = document.querySelector('messages-area');
// The controller wires up all the components and workers together,
// managing the dependencies. A kind of "DI" class.
let worker = null;
const integration = llm.replace('_api', '');
const worker_path_map = {
chatgpt: '../js/workers/model-worker-openai_responses.js',
google_gemini: '../js/workers/model-worker-google_gemini.js',
ollama: '../js/workers/model-worker-ollama.js',
openai_comp: '../js/workers/model-worker-openai_comp.js',
anthropic: '../js/workers/model-worker-anthropic.js',
};
switch (llm) {
case "chatgpt_api":
worker = new Worker('../js/workers/model-worker-openai.js', { type: 'module' });
break;
case "google_gemini_api":
worker = new Worker('../js/workers/model-worker-google_gemini.js', { type: 'module' });
break;
case "ollama_api":
worker = new Worker('../js/workers/model-worker-ollama.js', { type: 'module' });
break;
case "openai_comp_api":
worker = new Worker('../js/workers/model-worker-openai_comp.js', { type: 'module' });
break;
case "anthropic_api":
worker = new Worker('../js/workers/model-worker-anthropic.js', { type: 'module' });
break;
default:
console.error('[ThunderAI] API WebChat Unknown LLM type:', llm);
break;
const worker_path = worker_path_map[integration];
if (worker_path) {
worker = new Worker(worker_path, { type: 'module' });
} else {
console.error('[ThunderAI] API WebChat Unknown LLM type:', llm);
}
messagesArea.init(worker);
if (worker) {
messagesArea.init(worker);
messageInput.init(worker);
messageInput.setMessagesArea(messagesArea);
// Initialize the messageInput component and pass the worker to it
messageInput.init(worker);
messageInput.setMessagesArea(messagesArea);
if (integration_options_config[integration]) {
const integration_prefix = integration;
const options_config = integration_options_config[integration];
let prefsToGet = { do_debug: prefs_default.do_debug, hide_thinking: prefs_default.hide_thinking };
for (const key in options_config) {
prefsToGet[`${integration_prefix}_${key}`] = prefs_default[`${integration_prefix}_${key}`];
}
if (integration === 'openai_comp') {
prefsToGet.openai_comp_chat_name = prefs_default.openai_comp_chat_name;
}
switch (llm) {
case "chatgpt_api": {
let prefs_api = await browser.storage.sync.get({chatgpt_api_key: '', chatgpt_model: '', chatgpt_developer_messages:'', chatgpt_api_store: false, do_debug: false});
let i18nStrings = {};
i18nStrings["chatgpt_api_request_failed"] = browser.i18n.getMessage('chatgpt_api_request_failed');
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
messageInput.setModel(prefs_api.chatgpt_model);
messagesArea.setLLMName("ChatGPT");
worker.postMessage({ type: 'init', chatgpt_api_key: prefs_api.chatgpt_api_key, chatgpt_model: prefs_api.chatgpt_model, chatgpt_developer_messages: prefs_api.chatgpt_developer_messages, chatgpt_api_store: prefs_api.chatgpt_api_store, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings});
let additional_text = 'OpenAI Store: ' + (prefs_api.chatgpt_api_store ? 'Yes' : 'No');
if(prefs_api.chatgpt_developer_messages && prefs_api.chatgpt_developer_messages.length > 0) {
additional_text += "\n" + browser.i18n.getMessage("ChatGPT_Developer_Messages") + ": " + prefs_api.chatgpt_developer_messages;
let prefs_api = await browser.storage.sync.get(prefsToGet);
if (prompt_id) {
try {
const prompt = await loadPrompt(prompt_id);
if (prompt && prompt.api_type === llm) {
for (const key in options_config) {
const prefKey = `${integration_prefix}_${key}`;
if (prompt[prefKey] !== undefined) {
prefs_api[prefKey] = prompt[prefKey];
}
}
}
} catch (e) {
console.error("[ThunderAI] Error loading prompt settings:", e);
}
}
messagesArea.appendUserMessage(getAPIsInitMessageString("ChatGPT API", prefs_api.chatgpt_model, '', '', additional_text), "info");
browser.runtime.sendMessage({command: "openai_api_ready_" + call_id, window_id: (await browser.windows.getCurrent()).id});
break;
}
case "google_gemini_api": {
let prefs_api = await browser.storage.sync.get({google_gemini_api_key: '', google_gemini_model: '', google_gemini_system_instruction: '', do_debug: false});
let i18nStrings = {};
i18nStrings["google_gemini_api_request_failed"] = browser.i18n.getMessage('google_gemini_api_request_failed');
const i18n_msg_key = integration === 'openai_comp' ? 'OpenAIComp_api_request_failed' : `${integration}_api_request_failed`;
i18nStrings[i18n_msg_key] = browser.i18n.getMessage(i18n_msg_key);
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
messageInput.setModel(prefs_api.google_gemini_model);
messagesArea.setLLMName("Google Gemini");
let additional_text = '';
if(prefs_api.google_gemini_system_instruction && prefs_api.google_gemini_system_instruction.length > 0) {
additional_text += browser.i18n.getMessage("GoogleGemini_SystemInstruction") + ": " + prefs_api.google_gemini_system_instruction;
messageInput.setModel(prefs_api[`${integration_prefix}_model`]);
let llmName = "API";
switch(integration) {
case 'chatgpt': llmName = "ChatGPT"; break;
case 'google_gemini': llmName = "Google Gemini"; break;
case 'ollama': llmName = "Ollama Local"; break;
case 'openai_comp': llmName = prefs_api.openai_comp_chat_name || "OpenAI Comp"; break;
case 'anthropic': llmName = "Claude"; break;
}
worker.postMessage({ type: 'init', google_gemini_api_key: prefs_api.google_gemini_api_key, google_gemini_model: prefs_api.google_gemini_model, google_gemini_system_instruction: prefs_api.google_gemini_system_instruction, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings});
messagesArea.appendUserMessage(getAPIsInitMessageString("Google Gemini API", prefs_api.google_gemini_model, '', '', additional_text), "info");
browser.runtime.sendMessage({command: "google_gemini_api_ready_" + call_id, window_id: (await browser.windows.getCurrent()).id});
break;
}
case "ollama_api": {
let prefs_api = await browser.storage.sync.get({ollama_host: '', ollama_model: '', ollama_num_ctx: 0, ollama_think: false, do_debug: false});
let i18nStrings = {};
i18nStrings["ollama_api_request_failed"] = browser.i18n.getMessage('ollama_api_request_failed');
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
messageInput.setModel(prefs_api.ollama_model);
messagesArea.setLLMName("Ollama Local");
worker.postMessage({ type: 'init', ollama_host: prefs_api.ollama_host, ollama_model: prefs_api.ollama_model, ollama_num_ctx: prefs_api.ollama_num_ctx, ollama_think: prefs_api.ollama_think, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings});
browser.runtime.sendMessage({command: "ollama_api_ready_" + call_id, window_id: (await browser.windows.getCurrent()).id});
messagesArea.appendUserMessage(getAPIsInitMessageString("Ollama API", prefs_api.ollama_model, prefs_api.ollama_host), "info");
break;
}
case "openai_comp_api": {
let prefs_api = await browser.storage.sync.get({openai_comp_host: '', openai_comp_model: '', openai_comp_api_key: '', openai_comp_use_v1: true, openai_comp_chat_name: '', do_debug: false});
let i18nStrings = {};
i18nStrings["OpenAIComp_api_request_failed"] = browser.i18n.getMessage('OpenAIComp_api_request_failed');
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
messageInput.setModel(prefs_api.openai_comp_model);
messagesArea.setLLMName(prefs_api.openai_comp_chat_name);
worker.postMessage({ type: 'init', openai_comp_host: prefs_api.openai_comp_host, openai_comp_model: prefs_api.openai_comp_model, openai_comp_api_key: prefs_api.openai_comp_api_key, openai_comp_use_v1: prefs_api.openai_comp_use_v1, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings});
messagesArea.appendUserMessage(getAPIsInitMessageString("OpenAI Compatible API", prefs_api.openai_comp_model, prefs_api.openai_comp_host), "info");
browser.runtime.sendMessage({command: "openai_comp_api_ready_" + call_id, window_id: (await browser.windows.getCurrent()).id});
break;
}
case "anthropic_api": {
let prefs_api = await browser.storage.sync.get({anthropic_api_key: '', anthropic_model: '', anthropic_version: '2023-06-01', anthropic_max_tokens: 4096, do_debug: false});
let i18nStrings = {};
i18nStrings["anthropic_api_request_failed"] = browser.i18n.getMessage('anthropic_api_request_failed');
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
messageInput.setModel(prefs_api.anthropic_model);
messagesArea.setLLMName("Anthropic");
worker.postMessage({ type: 'init', anthropic_api_key: prefs_api.anthropic_api_key, anthropic_model: prefs_api.anthropic_model, anthropic_version: prefs_api.anthropic_version, anthropic_max_tokens: prefs_api.anthropic_max_tokens, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings});
messagesArea.appendUserMessage(getAPIsInitMessageString("Anthropic API", prefs_api.anthropic_model, '', prefs_api.anthropic_version), "info");
browser.runtime.sendMessage({command: "anthropic_api_ready_" + call_id, window_id: (await browser.windows.getCurrent()).id});
break;
messagesArea.setLLMName(llmName);
messagesArea.setHideThinking(!!prefs_api.hide_thinking);
document.title += " [" + llmName + " | " + decodeURIComponent(prompt_name) + "]";
document.title += " [" + llmName + " | " + decodeURIComponent(prompt_name) + "]";
let workerInitMessage = {
type: 'init',
do_debug: prefs_api.do_debug,
i18nStrings: i18nStrings,
};
for (const key in options_config) {
const prefKey = `${integration_prefix}_${key}`;
workerInitMessage[prefKey] = prefs_api[prefKey];
}
worker.postMessage(workerInitMessage);
const additional_messages_config = {
chatgpt: [
{ key: 'store', labelKey: 'ChatGPT_chatgpt_api_store', type: 'boolean' },
{ key: 'developer_messages', labelKey: 'ChatGPT_Developer_Messages', type: 'string' },
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }
],
google_gemini: [
{ key: 'system_instruction', labelKey: 'GoogleGemini_SystemInstruction', type: 'string' },
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' },
{ key: 'thinking_budget', labelKey: 'prefs_google_gemini_thinking_budget', type: 'string' }
],
ollama: [
{ key: 'think', labelKey: 'prefs_ollama_think', type: 'boolean' },
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' },
{ key: 'num_ctx', labelKey: 'prefs_ollama_num_ctx', type: 'number_gt_zero' }
],
openai_comp: [
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }
],
anthropic: [
{ key: 'system_prompt', labelKey: 'Anthropic_System_Prompt', type: 'string' },
{ key: 'max_tokens', labelKey: 'prefs_OptionText_anthropic_max_tokens', type: 'number_gt_zero' },
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' },
{ key: 'extended_thinking_budget', labelKey: 'prefs_OptionText_anthropic_extended_thinking_budget', type: 'number_gt_zero' }
]
};
const getAdditionalMessages = (integration, prefs) => {
const messages = [];
const config = additional_messages_config[integration];
if (!config) return messages;
for (const item of config) {
const prefKey = `${integration}_${item.key}`;
const value = prefs[prefKey];
if (value !== undefined && value !== null && value !== '') {
let displayValue;
let shouldAdd = false;
switch (item.type) {
case 'boolean':
displayValue = value ? 'Yes' : 'No';
shouldAdd = true;
break;
case 'string':
if (value.length > 0) {
displayValue = value;
shouldAdd = true;
}
break;
case 'number_gt_zero':
if (value > 0) {
displayValue = value;
shouldAdd = true;
}
break;
}
if (shouldAdd) {
messages.push({ label: browser.i18n.getMessage(item.labelKey), value: displayValue });
}
}
}
return messages;
};
let additional_text_elements = [];
additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
additional_text_elements.push(...getAdditionalMessages(integration, prefs_api));
const api_strings = {
chatgpt: "ChatGPT API",
google_gemini: "Google Gemini API",
ollama: "Ollama API",
openai_comp: "OpenAI Compatible API",
anthropic: "Claude API"
};
messagesArea.appendUserMessage(getAPIsInitMessageString({
api_string: api_strings[integration],
model_string: prefs_api[`${integration_prefix}_model`],
host_string: prefs_api[`${integration_prefix}_host`],
version_string: prefs_api[`${integration_prefix}_version`],
additional_messages: additional_text_elements
}), "info");
//console.log(`>>>>>>>>>>>>> command: ${llm}_ready_${call_id}`,)
browser.runtime.sendMessage({
command: `${llm}_ready_${call_id}`,
window_id: (await browser.windows.getCurrent()).id
});
}
}
@ -155,13 +242,17 @@ worker.onmessage = async function(event) {
messagesArea.handleNewToken(payload.token);
messageInput.setStatusMessage(browser.i18n.getMessage("apiwebchat_receiving_data") + '...');
break;
case 'newThinkingToken':
messagesArea.handleNewThinkingToken(payload.token);
messageInput.setStatusMessage(browser.i18n.getMessage("apiwebchat_receiving_data") + '...');
break;
case 'tokensDone':
await messagesArea.handleTokensDone(promptData);
messageInput.enableInput();
break;
case 'error':
messagesArea.appendBotMessage(payload,'error');
messageInput.enableInput();
messageInput.enableInput(false);
break;
default:
console.error('[ThunderAI] Unknown event type from API worker:', type);
@ -175,34 +266,46 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
promptData = message;
//send the received prompt to the llm api
if(message.do_custom_text=="1") {
messageInput._showCustomTextField();
messageInput._showCustomTextField(message.prompt_info?.custom_text_array);
}else{
sendPrompt(message);
}
break;
case 'api_send_custom_text':
let userInput = message.custom_text;
let userInput = message.custom_text; // From version 4.0.0 this is an array
if(userInput !== null) {
if(!placeholdersUtils.hasPlaceholder(promptData.prompt, 'additional_text')){
// no additional_text placeholder, do as usual
promptData.prompt += " " + userInput;
const inputText = Array.isArray(userInput) ? userInput.map(obj => obj.custom_text).join(' ') : userInput;
promptData.prompt += " " + inputText;
}else{
// we have the additional_text placeholder, do the magic!
let finalSubs = {};
finalSubs["additional_text"] = userInput;
promptData.prompt = placeholdersUtils.replacePlaceholders(promptData.prompt, finalSubs, ph_def_val==='1')
if (Array.isArray(userInput)) {
userInput.forEach(obj => {
finalSubs[obj.placeholder.replace(/^{%|%}$/g, '').trim()] = obj.custom_text;
});
} else {
finalSubs["additional_text"] = userInput;
}
promptData.prompt = placeholdersUtils.replacePlaceholders({
text: promptData.prompt,
replacements: finalSubs,
use_default_value: ph_def_val==='1'
})
}
sendPrompt(promptData);
}
break;
case "api_error":
messagesArea.appendBotMessage(message.error,'error');
messageInput.enableInput();
messageInput.enableInput(false);
break;
}
});
function sendPrompt(message){
messageInput._setMessageInputValue(message.prompt);
messageInput._setMessageInputValue(convertNewlinesToBr(message.prompt));
messageInput._handleNewChatMessage();
}
}

View file

@ -3,7 +3,6 @@
<head>
<!-- Other meta tags and stylesheets -->
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<!-- Use the custom tags directly -->

View file

@ -1,6 +1,6 @@
/*
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
* Copyright (C) 2024 - 2025 Mic (m@micz.it)
* Copyright (C) 2024 - 2026 Mic (m@micz.it)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -49,6 +49,7 @@ messagesInputStyle.textContent = `
height: 36px;
cursor: pointer;
border-radius: 10px;
border: 1px outset buttonface;
}
#stopButton {
width: 44px;
@ -65,15 +66,44 @@ messagesInputStyle.textContent = `
border-radius: 5px;
padding: 5px;
background: #F2F2F2;
display: flex;
align-items: center;
gap: 3px;
}
#statusLoggerImg{
display: none;
vertical-align: middle;
}
#statusLoggerText{
font-weight: 600;
}
#statusLogger.status-working{
border-color: #2196F3;
background: #E3F2FD;
color: #1565C0;
}
#statusLogger.status-done{
border-color: #4CAF50;
background: #E8F5E9;
color: #2E7D32;
}
@keyframes statusFadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
#statusLogger.status-fadeout{
animation: statusFadeOut 0.5s ease-out forwards;
}
#mzta-custom_text{
padding:10px;
width:auto;
width:50%;
min-width:300px;
max-width:80%;
height:auto;
max-height:80%;
border-radius:5px;
overflow:auto;
overflow-y:auto;
overflow-x:hidden;
position:fixed;
top:50%;
left:50%;
@ -83,15 +113,18 @@ messagesInputStyle.textContent = `
background:#333;
color:white;
border:3px solid white;
box-sizing: border-box;
}
#mzta-custom_loading{
height:50px;display:none;
}
#mzta-custom_textarea{
color:black;
padding:1px;
padding:5px;
font-size:15px;
width:100%;
box-sizing: border-box;
resize: vertical;
}
#mzta-custom_info{
text-align:center;
@ -99,6 +132,19 @@ messagesInputStyle.textContent = `
padding-bottom:10px;
font-size:15px;
}
#mzta-custom_info span{
font-size:0.8em;
}
#mzta-custom_step{
position: absolute;
bottom: 5px;
right: 10px;
font-size: 12px;
color: #ccc;
}
#mzta-custom_btn{
margin-top:7px;
}
@media (prefers-color-scheme: dark) {
#messageInputField {
background-color: #303030;
@ -108,6 +154,16 @@ messagesInputStyle.textContent = `
background: #212121;
color: #ffffff;
}
#statusLogger.status-working{
border-color: #64B5F6;
background: #1A3A5C;
color: #90CAF9;
}
#statusLogger.status-done{
border-color: #81C784;
background: #1B3D1E;
color: #A5D6A7;
}
}
`;
messageInputTemplate.content.appendChild(messagesInputStyle);
@ -164,8 +220,14 @@ messageInputTemplate.content.appendChild(stopButton);
const statusLogger = document.createElement('div');
statusLogger.id = 'statusLogger';
statusLogger.textContent = '';
statusLogger.style.display = 'none';
const statusLoggerImg = document.createElement('img');
statusLoggerImg.id = 'statusLoggerImg';
statusLoggerImg.src = browser.runtime.getURL('/images/mzta-loading.svg');
statusLogger.appendChild(statusLoggerImg);
const statusLoggerText = document.createElement('span');
statusLoggerText.id = 'statusLoggerText';
statusLogger.appendChild(statusLoggerText);
messageInputTemplate.content.appendChild(statusLogger);
//div per custom text
@ -177,6 +239,7 @@ customInfo.textContent = browser.i18n.getMessage("chatgpt_win_custom_text");
customDiv.appendChild(customInfo);
const customTextArea = document.createElement('textarea');
customTextArea.id = 'mzta-custom_textarea';
customTextArea.rows = 5;
customDiv.appendChild(customTextArea);
const customLoading = document.createElement('img');
customLoading.src = browser.runtime.getURL("/images/loading.gif");
@ -187,11 +250,17 @@ customBtn.id = 'mzta-custom_btn';
customBtn.textContent = browser.i18n.getMessage("chatgpt_win_send");
customBtn.classList.add('mzta-btn');
customDiv.appendChild(customBtn);
const customStep = document.createElement('div');
customStep.id = 'mzta-custom_step';
customDiv.appendChild(customStep);
messageInputTemplate.content.appendChild(customDiv);
class MessageInput extends HTMLElement {
model = '';
_doneTimeout = null;
_customTextArray = [];
_currentCustomTextIndex = 0;
constructor() {
super();
@ -202,6 +271,8 @@ class MessageInput extends HTMLElement {
this._sendButton = shadowRoot.querySelector('#sendButton');
this._stopButton = shadowRoot.querySelector('#stopButton');
this._statusLogger = shadowRoot.querySelector('#statusLogger');
this._statusLoggerImg = shadowRoot.querySelector('#statusLoggerImg');
this._statusLoggerText = shadowRoot.querySelector('#statusLoggerText');
this._messageInputField.addEventListener('keydown', this._handleKeyDown.bind(this));
this._sendButton.addEventListener('click', this._handleClick.bind(this));
@ -211,8 +282,14 @@ class MessageInput extends HTMLElement {
this._customTextArea = shadowRoot.querySelector('#mzta-custom_textarea');
this._customLoading = shadowRoot.querySelector('#mzta-custom_loading');
this._customBtn = shadowRoot.querySelector('#mzta-custom_btn');
this._customStep = shadowRoot.querySelector('#mzta-custom_step');
this._customBtn.addEventListener("click", () => { this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}) });
this._customTextArea.addEventListener("keydown", (event) => { if(event.code == "Enter" && event.ctrlKey) this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText}) });
this._customTextArea.addEventListener("keydown", (event) => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
this._customTextBtnClick({customBtn:this._customBtn,customLoading:this._customLoading,customDiv:this._customText});
}
});
}
connectedCallback() {
@ -239,7 +316,7 @@ class MessageInput extends HTMLElement {
this._messageInputField.value = '';
}
enableInput() {
enableInput(showDone = true) {
// console.log("[ThunderAI] enableInput");
this._messageInputField.value = '';
this._messageInputField.removeAttribute('disabled');
@ -248,20 +325,56 @@ class MessageInput extends HTMLElement {
this._stopButton.setAttribute('disabled', 'disabled');
this._stopButton.style.display = 'none';
this._stopButton.title = browser.i18n.getMessage("chagpt_api_send_button") + ": " + this.model;
this.hideStatusMessage();
this.setStatusMessage('');
if (showDone) {
this.showDoneStatus();
} else {
this.hideStatusMessage();
this.setStatusMessage('');
}
}
setStatusMessage(message) {
this._statusLogger.textContent = message;
this._statusLoggerText.textContent = message;
}
showStatusMessage() {
this._statusLogger.style.display = 'block';
showStatusMessage(state = 'working') {
if (this._doneTimeout) {
clearTimeout(this._doneTimeout);
this._doneTimeout = null;
}
this._setStatusClass('status-' + state);
this._statusLogger.style.display = 'flex';
}
hideStatusMessage() {
this._statusLogger.style.display = 'none';
this._statusLoggerImg.style.display = 'none';
this._setStatusClass(null);
}
_setStatusClass(className) {
this._statusLogger.classList.remove('status-working', 'status-done', 'status-fadeout');
if (className) {
this._statusLogger.classList.add(className);
}
}
showDoneStatus() {
if (this._doneTimeout) {
clearTimeout(this._doneTimeout);
}
this._statusLoggerImg.style.display = 'none';
this.setStatusMessage(browser.i18n.getMessage('apiwebchat_done'));
this._setStatusClass('status-done');
this._statusLogger.style.display = 'flex';
this._doneTimeout = setTimeout(() => {
this._statusLogger.classList.add('status-fadeout');
this._doneTimeout = setTimeout(() => {
this.hideStatusMessage();
this.setStatusMessage('');
}, 500);
}, 1500);
}
_handleKeyDown(event) {
@ -297,6 +410,7 @@ class MessageInput extends HTMLElement {
this.messagesAreaComponent.appendUserMessage(messageContent);
}
this.setStatusMessage(browser.i18n.getMessage('WaitingServerResponse') + '...');
this._statusLoggerImg.style.display = 'inline';
this.showStatusMessage();
this.worker.postMessage({ type: 'chatMessage', message: messageContent });
}
@ -305,21 +419,64 @@ class MessageInput extends HTMLElement {
this._messageInputField.value = msg;
}
_showCustomTextField(){
_showCustomTextField(custom_text_array){
this._customTextArray = custom_text_array || [];
if (this._customTextArray.length === 0) {
this._customTextArray.push({ placeholder: "{%additional_text%}", info: "" });
}
this._currentCustomTextIndex = 0;
this._customText.style.display = 'block';
this._renderCustomTextStep();
}
_renderCustomTextStep() {
const currentItem = this._customTextArray[this._currentCustomTextIndex];
const infoDiv = this.shadowRoot.querySelector('#mzta-custom_info');
this._customTextArea.value = "";
infoDiv.textContent = browser.i18n.getMessage("chatgpt_win_custom_text");
if (currentItem.info && currentItem.info.trim() !== "") {
infoDiv.appendChild(document.createElement("br"));
const infoSpan = document.createElement("span");
infoSpan.textContent = "[" + browser.i18n.getMessage("customPrompts_form_label_ID") + ": " + currentItem.info + "]";
infoDiv.appendChild(infoSpan);
}
if(this._customTextArray.length > 1) {
this._customStep.textContent = (this._currentCustomTextIndex + 1) + "/" + this._customTextArray.length;
this._customStep.style.display = 'block';
} else {
this._customStep.style.display = 'none';
}
this._customTextArea.focus();
}
async _customTextBtnClick(args) {
const customText = this._customTextArea.value;
// console.log(">>>>>>>>>>>>>>>> customText: " + customText);
args.customBtn.disabled = true;
args.customBtn.classList.add('disabled');
args.customLoading.style.display = 'inline-block';
args.customLoading.style.display = 'none';
let tab = await browser.tabs.query({ active: true, currentWindow: true });
browser.runtime.sendMessage({ command: "api_send_custom_text", custom_text: customText, tabId: tab[0].id });
args.customDiv.style.display = 'none';
if (this._customTextArray[this._currentCustomTextIndex]) {
this._customTextArray[this._currentCustomTextIndex].custom_text = customText;
}
this._currentCustomTextIndex++;
if (this._currentCustomTextIndex < this._customTextArray.length) {
this._renderCustomTextStep();
} else {
args.customBtn.disabled = true;
args.customBtn.classList.add('disabled');
args.customLoading.style.display = 'inline-block';
let tab = await browser.tabs.query({ active: true, currentWindow: true });
browser.runtime.sendMessage({ command: "api_send_custom_text", custom_text: this._customTextArray, tabId: tab[0].id });
args.customDiv.style.display = 'none';
args.customBtn.disabled = false;
args.customBtn.classList.remove('disabled');
args.customLoading.style.display = 'none';
}
}
}

View file

@ -1,6 +1,6 @@
/*
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
* Copyright (C) 2024 - 2025 Mic (m@micz.it)
* Copyright (C) 2024 - 2026 Mic (m@micz.it)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,6 +20,7 @@
* The original code has been released under the Apache License, Version 2.0.
*/
import { prefs_default } from '../options/mzta-options-default.js';
const messagesAreaTemplate = document.createElement('template');
const messagesAreaStyle = document.createElement('style');
@ -103,6 +104,10 @@ messagesAreaStyle.textContent = `
background: lightblue;
color: navy;
margin-bottom: var(--margin);
font-size: 0.8em;
}
.info_obj{
color:rgb(0, 71, 36);
}
.sel_info{
font-size: 0.7rem;
@ -189,6 +194,25 @@ messagesAreaStyle.textContent = `
display: flex;
}
/* Thinking block styles */
details.thinking-block {
border-left: 3px solid #bbb;
background: #f7f7f7;
padding: 0.3em 0.6em;
margin: 0 0 0.6em 0;
font-size: 0.9em;
color: #555;
border-radius: 4px;
}
details.thinking-block > summary {
cursor: pointer;
font-weight: 600;
}
details.thinking-block .thinking-content {
white-space: pre-wrap;
margin-top: 0.3em;
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
.added {
@ -197,6 +221,11 @@ messagesAreaStyle.textContent = `
.removed {
background-color:rgb(90, 0, 0);
}
details.thinking-block {
background: #2a2a2a;
color: #bbb;
border-left-color: #555;
}
}
`;
messagesAreaTemplate.content.appendChild(messagesAreaStyle);
@ -213,6 +242,8 @@ class MessagesArea extends HTMLElement {
constructor() {
super();
this.accumulatingMessageEl = null;
this.thinkingAccumulator = '';
this.hideThinking = false;
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(messagesAreaTemplate.content.cloneNode(true));
@ -243,6 +274,14 @@ class MessagesArea extends HTMLElement {
this.llmName = llmName;
}
setHideThinking(val) {
this.hideThinking = !!val;
}
handleNewThinkingToken(token) {
this.thinkingAccumulator += token;
}
async handleTokensDone(promptData = null) {
this.flushAccumulatingMessage();
await this.addActionButtons(promptData);
@ -268,7 +307,11 @@ class MessagesArea extends HTMLElement {
const messageElement = document.createElement('div');
messageElement.classList.add('message', type);
// Replace \n with <br> for correct HTML display
messageElement.appendChild(htmlStringToFragment(messageText));
if (type === "info") {
messageElement.appendChild(htmlStringToFragment(messageText));
} else {
messageElement.appendChild(textWithBrToFragment(messageText));
}
// messageElement.textContent = messageText;
// // Replace \n with <br> elements for correct HTML display
// messageElement.innerHTML = '';
@ -379,7 +422,7 @@ class MessagesArea extends HTMLElement {
splitButton.appendChild(actionButton);
const fullTextHTMLAtAssignment = this.fullTextHTML.trim().replace(/^"|"$/g, '').replace(/^<p>&quot;/, '<p>').replace(/&quot;<\/p>$/, '</p>'); // strip quotation marks
//console.log(">>>>>>>>>>>> fullTextHTMLAtAssignment: " + fullTextHTMLAtAssignment);
let reply_type_pref = await browser.storage.sync.get({reply_type: 'reply_all'});
let reply_type_pref = await browser.storage.sync.get({ reply_type: prefs_default.reply_type });
if((promptData.action == "1") && (promptData.mailMessageId != -1)) {
const actionButton_line2 = document.createElement('span');
actionButton_line2.classList.add('action_btn_info');
@ -444,11 +487,34 @@ class MessagesArea extends HTMLElement {
closeButton.addEventListener('click', async () => {
browser.runtime.sendMessage({command: "chatgpt_close", window_id: (await browser.windows.getCurrent()).id}); // close window
});
if(promptData.action != 0) {
if(promptData.action != 0) {
actionButtons.appendChild(splitButton);
selectionInfo.style.display = "block"; // show selection info
}
// Save as Summary button (only shown for summary webchat sessions)
if(promptData.prompt_info?.headerMessageId && promptData.prompt_info?.summaryTabId) {
const saveSummaryButton = document.createElement('button');
saveSummaryButton.textContent = browser.i18n.getMessage("webchat_save_as_summary");
saveSummaryButton.classList.add('action_btn');
saveSummaryButton.addEventListener('click', async () => {
let finalText = removeAloneBRs(fullTextHTMLAtAssignment);
const selectedHTML = this.getCurrentSelectionHTML();
if(selectedHTML != "") {
finalText = removeAloneBRs(selectedHTML);
}
await browser.runtime.sendMessage({
command: "chatgpt_saveSummary",
text: finalText,
headerMessageId: promptData.prompt_info.headerMessageId,
tabId: promptData.prompt_info.summaryTabId || promptData.tabId,
});
browser.runtime.sendMessage({command: "chatgpt_close", window_id: (await browser.windows.getCurrent()).id});
});
actionButtons.appendChild(saveSummaryButton);
selectionInfo.style.display = "block";
}
// diff viewer button
if(promptData.prompt_info?.use_diff_viewer == "1") {
const diffvButton = document.createElement('button');
@ -486,22 +552,29 @@ class MessagesArea extends HTMLElement {
// Iterate over each part of the diff to create the HTML output
wordDiff.forEach(part => {
const diffElement = document.createElement("span");
// Apply a different class depending on whether the word is added, removed, or unchanged
if (part.added) {
diffElement.className = "added";
diffElement.textContent = part.value;
} else if (part.removed) {
diffElement.className = "removed";
diffElement.textContent = part.value;
} else {
diffElement.textContent = part.value;
// Split part.value by <br> (handling <br>, <br/>, <br />)
const brRegex = /(<br\s*\/?>)/gi;
const segments = part.value.split(brRegex);
segments.forEach(segment => {
if (segment.match(brRegex)) {
// It's a <br>, add a real <br> element
messageElement.appendChild(document.createElement("br"));
} else if (segment.length > 0) {
const diffElement = document.createElement("span");
if (part.added) {
diffElement.className = "added";
diffElement.textContent = segment;
} else if (part.removed) {
diffElement.className = "removed";
diffElement.textContent = segment;
} else {
diffElement.textContent = segment;
}
messageElement.appendChild(diffElement);
}
// Add the element to the container
messageElement.appendChild(diffElement);
});
});
});
const header = document.createElement('h2');
header.textContent = browser.i18n.getMessage("chatgpt_win_diff_title");
@ -519,23 +592,67 @@ class MessagesArea extends HTMLElement {
this.accumulatingMessageEl.querySelectorAll('.token').forEach(tokenEl => {
fullText += tokenEl.textContent;
});
// If an unterminated <think> block is present (mid-stream), defer the
// markdown render until the closing tag arrives — tokens stay in the DOM
// as raw fading spans, but the partial <think> content is never sent
// through markdown-it or promoted to the final thinking block.
const openThink = fullText.match(/<think>/i);
const closeThink = fullText.match(/<\/think>/i);
if (openThink && !closeThink) {
return;
}
// Extract inline <think>...</think> blocks (Ollama / OpenAI Comp) and strip them from fullText.
let inlineThinking = '';
const thinkRegex = /<think>([\s\S]*?)<\/think>/gi;
let match;
while ((match = thinkRegex.exec(fullText)) !== null) {
inlineThinking += (inlineThinking ? '\n' : '') + match[1];
}
fullText = fullText.replace(thinkRegex, '').replace(/^\s+/, '');
// Combined thinking content: worker-side (Anthropic) + inline (<think> tags)
let combinedThinking = this.thinkingAccumulator;
if (inlineThinking) {
combinedThinking += (combinedThinking ? '\n' : '') + inlineThinking;
}
this.thinkingAccumulator = '';
// Convert Markdown to DOM nodes using the markdown-it library
const md = window.markdownit();
const html = convertNewlinesToBr(md.render(fullText));
const html = md.render(fullText);
this.fullTextHTML += html;
// console.log(">>>>>>>>>>>>>>>> flushAccumulatingMessage this.fullTextHTML: " + this.fullTextHTML);
// Create a new DOM parser
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
convertTextNodeNewlinesToBr(doc.body);
// Remove existing tokens
while (this.accumulatingMessageEl.firstChild) {
this.accumulatingMessageEl.removeChild(this.accumulatingMessageEl.firstChild);
}
// Prepend thinking block (if any). hide_thinking controls the initial
// open/collapsed state: true -> collapsed, false -> open. Users can always
// toggle with a click.
if (combinedThinking) {
const details = document.createElement('details');
details.classList.add('thinking-block');
if (!this.hideThinking) details.open = true;
const summary = document.createElement('summary');
summary.textContent = browser.i18n.getMessage('prefs_OptionText_thinking_summary') || 'Thinking';
const content = document.createElement('div');
content.classList.add('thinking-content');
content.textContent = combinedThinking;
details.appendChild(summary);
details.appendChild(content);
this.accumulatingMessageEl.appendChild(details);
}
// Append new nodes
Array.from(doc.body.childNodes).forEach(node => {
@ -563,6 +680,20 @@ class MessagesArea extends HTMLElement {
customElements.define('messages-area', MessagesArea);
function textWithBrToFragment(text) {
const fragment = document.createDocumentFragment();
const segments = text.split(/<br\s*\/?>/gi);
segments.forEach((segment, idx) => {
if (segment.length > 0) {
fragment.appendChild(document.createTextNode(segment));
}
if (idx < segments.length - 1) {
fragment.appendChild(document.createElement('br'));
}
});
return fragment;
}
function htmlStringToFragment(htmlString) {
// console.log(">>>>>>>>>>>>>>>> htmlStringToFragment htmlString: " + htmlString);
const normalizedHtml = htmlString.replace(/\n/g, '<br>');
@ -574,8 +705,23 @@ function htmlStringToFragment(htmlString) {
return fragment;
}
function convertNewlinesToBr(text) {
return text.replace(/\n/g, '<br>');
function convertTextNodeNewlinesToBr(element) {
element.childNodes.forEach(node => {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent.includes('\n') && node.textContent.trim() !== '') {
const fragment = document.createDocumentFragment();
node.textContent.split('\n').forEach((part, idx, arr) => {
fragment.appendChild(document.createTextNode(part));
if (idx < arr.length - 1) {
fragment.appendChild(document.createElement('br'));
}
});
node.parentNode.replaceChild(fragment, node);
}
} else if (node.nodeType === Node.ELEMENT_NODE) {
convertTextNodeNewlinesToBr(node);
}
});
}
function removeAloneBRs(htmlString) {
@ -602,4 +748,4 @@ function removeAloneBRs(htmlString) {
});
return doc.body.innerHTML;
}
}

View file

@ -0,0 +1,230 @@
# Architecture
## Extension Structure (Manifest V2)
ThunderAI runs as a standard Thunderbird WebExtension with three main execution contexts:
```
Background Page → mzta-background.html / mzta-background.js
Popup → popup/mzta-popup.html / popup/mzta-popup.js
Options Page → options/mzta-options.html / options/mzta-options.js
Feature Pages → pages/*/
Content Script → js/lib/diff.js (injected into chatgpt.com)
Web Workers → js/workers/model-worker-*.js (one per API provider)
```
## Data Flow: User Action → AI Response
```
User clicks popup or presses Ctrl+Alt+A
popup/mzta-popup.js (renders prompt list, handles selection)
↓ (sendMessage to background)
mzta-background.js (orchestrates everything)
js/mzta-placeholders.js (resolves {%placeholder%} values from email data)
js/mzta-prompts.js (builds final prompt string)
┌─────────────────────────────────────────┐
│ Based on connection_type: │
│ chatgpt_web → js/mzta-chatgpt.js │ (opens ChatGPT window)
│ chatgpt_api → Web Worker (openai) │
│ ollama_api → Web Worker (ollama) │
│ google_gemini → Web Worker (gemini) │
│ anthropic → Web Worker (anthropic)│
│ openai_comp → Web Worker (comp) │
└─────────────────────────────────────────┘
Result returned to background
js/mzta-compose-script.js (inserts text into Thunderbird compose window and display window)
```
### Data Flow: Inline Summary on Message Display
The `summarize_display_mode` preference (`'inline'` or `'webchat'`) controls where
the summary is displayed. The `summarize_auto` preference controls when it is triggered.
- `summarize_auto = 2` (automatic) always generates inline, regardless of `summarize_display_mode`.
- `summarize_auto = 3` (on receive) pre-caches the summary silently when the email arrives via `onNewMailReceived`. When the user later opens the message, the cache hit triggers an instant display.
- `summarize_auto = 1` (manual button) respects `summarize_display_mode`:
- `'inline'` → button click triggers inline generation
- `'webchat'` → button click opens the AI chat window via `_openSummaryWebchat()`
- Context menu summarize also respects `summarize_display_mode`:
- `'inline'` with a single message → generates inline via `_generateSummaryForMessage()`
- `'webchat'` or multiple messages → opens the AI chat window via `openChatGPT()`
```
User opens/selects a message in Thunderbird
mzta-compose-script.js (sends "initSummary" to background)
mzta-background.js (checks summarize_auto + summarize_display_mode prefs)
┌──────────────────────────────────────────────────────────┐
│ summarize_auto = 0 → do nothing │
│ summarize_auto = 1 → show "click to generate" button │
│ display_mode = inline → click triggers inline gen │
│ display_mode = webchat → click opens chat window │
│ summarize_auto = 2 → generate immediately (always inline)│
│ summarize_auto = 3 → cache hit (pre-cached on receive) │
└──────────────────────────────────────────────────────────┘
↓ (if generating inline)
taSummaryStore (check cache / set processing)
↓ (cache miss)
mzta-special-commands (via Web Worker, NOT chatgpt_web)
taSummaryStore (save result via taStorage)
mzta-compose-script.js (render summary banner in message body)
```
### Data Flow: Inline Translation on Message Display
The `translate_auto` preference controls when translation is triggered.
Translation always renders inline (webchat mode has been removed).
The target language is determined by `translate_lang` (fallback on `default_chatgpt_lang`).
```
User opens/selects a message in Thunderbird
mzta-compose-script.js (sends "initTranslation" to background)
mzta-background.js (checks translate + translate_auto prefs)
┌──────────────────────────────────────────────────────────┐
│ translate_auto = 0 → do nothing │
│ translate_auto = 1 → show "click to translate" button │
│ translate_auto = 2 → generate immediately │
└──────────────────────────────────────────────────────────┘
taTranslationStore (check cache / set processing)
↓ (cache miss)
mzta-special-commands (via Web Worker, NOT chatgpt_web)
taTranslationStore (save result via taStorage)
mzta-compose-script.js (render translation banner in message body)
```
### Data Flow: Background Summary on Email Receive (summarize_auto = 3)
When `summarize_auto = 3`, a summary is generated silently when a new email arrives. The flow mirrors `add_tags_auto`:
```
New email arrives
browser.messages.onNewMailReceived
newEmailListener (checks _process_incoming, which includes summarize_auto === 3)
processEmails({ summarizeOnReceive: true })
↓ (single loop — shared with addTagsAuto / spamFilter / translateOnReceive)
_generateSummaryForMessage(headerMessageId, null, { messageData })
← tabId is null → no UI messages sent, silent pre-cache
taSummaryStore.saveSummary()
[later] user opens the message → initSummary → cache hit → showSummary instantly
```
### Data Flow: Background Translation on Email Receive (translate_auto = 3)
When `translate_auto = 3`, a translation is generated silently when a new email arrives. Mirrors the summarize on-receive flow:
```
New email arrives
browser.messages.onNewMailReceived
newEmailListener (checks _process_incoming, which includes translate_auto === 3)
processEmails({ translateOnReceive: true })
↓ (single loop — shared with addTagsAuto / spamFilter / summarizeOnReceive)
_generateTranslationForMessage(headerMessageId, null, { messageData })
← tabId is null → no UI messages sent, silent pre-cache
taTranslationStore.saveTranslation()
[later] user opens the message → initTranslation → cache hit → showTranslation instantly
```
## Key Modules
| File | Role |
|------|------|
| `mzta-background.js` | Main orchestrator: listens for messages, coordinates all features |
| `js/mzta-menus.js` | Context menu creation and management |
| `js/mzta-prompts.js` | Prompt definitions (built-in) and custom prompt loading |
| `js/mzta-placeholders.js` | Placeholder definitions and resolution logic |
| `js/mzta-utils.js` | General utilities (email parsing, storage helpers, etc.) |
| `js/mzta-utils-prompt.js` | Prompt-specific utilities (text truncation, lang injection, `buildSummaryPrompt()` for unified summary prompt assembly, `buildTranslationPrompt()` for translation prompt assembly) |
| `js/mzta-compose-script.js` | Content script for compose and message display: injects AI response into compose window, renders unified toolbar (spam badge, summary/translation trigger buttons) and content panels (generic error, spam explanation, summary, translation) in message display via `#mzta-container` |
| `js/mzta-chatgpt.js` | ChatGPT Web integration (opens browser window, reads DOM) |
| `js/mzta-special-commands.js` | Handles special prompt actions (add_tags, calendar, task) |
| `js/mzta-spamreport.js` | Spam filter logic |
| `js/mzta-i18n.js` | i18n helper (wraps `browser.i18n.getMessage`) |
| `js/mzta-logger.js` | Debug logging (gated by `do_debug` pref) |
| `js/mzta-store.js` | Storage abstraction helpers |
| `js/mzta-storage.js` | Unified per-message storage layer (`taStorage` class) for summary, spam, and translation data |
| `js/mzta-summarystore.js` | Summary-specific storage wrapper (`taSummaryStore` class) with caching, truncation, and processing-state tracking |
| `js/mzta-translationstore.js` | Translation-specific storage wrapper (`taTranslationStore` class) with caching, truncation, and processing-state tracking |
| `js/mzta-working-status.js` | Visual status indicator during AI processing |
| `js/mzta-addtags-exclusion-list.js` | Tag exclusion list management |
| `js/mzta-placeholders-autocomplete.js` | Autocomplete for placeholders in prompt editor |
## API Modules (`js/api/`)
Each file handles HTTP communication for one provider:
| File | Provider |
|------|----------|
| `anthropic.js` | Claude (Anthropic) API |
| `google_gemini.js` | Google Gemini API |
| `ollama.js` | Ollama (self-hosted) |
| `openai_comp.js` | OpenAI-compatible APIs |
| `openai_comp_configs.js` | Pre-configured providers (DeepSeek, Grok, Mistral, OpenRouter, Perplexity) |
| `openai_responses.js` | OpenAI Responses API |
## Web Workers (`js/workers/`)
Each API provider has a dedicated Web Worker so API calls don't block the UI:
- `model-worker-anthropic.js`
- `model-worker-google_gemini.js`
- `model-worker-ollama.js`
- `model-worker-openai_comp.js`
- `model-worker-openai_responses.js`
Workers receive a message with the prompt and settings, make the API call, and post back the result.
## Feature Pages (`pages/`)
Each subdirectory is a self-contained settings/UI page for a specific feature:
| Directory | Feature |
|-----------|---------|
| `addtags/` | Auto-tagging configuration |
| `customprompts/` | Custom prompt editor |
| `customdataplaceholders/` | Custom placeholder editor |
| `get-calendar-event/` | Calendar event extraction settings |
| `get-task/` | Task creation settings |
| `menu_order/` | Drag-and-drop reordering and visibility control for popup and context menus |
| `spamfilter/` | Spam filter settings |
| `summarize/` | Email summarization settings |
| `translate/` | Email translation settings |
| `onboarding/` | First-run welcome page |
| `_lib/` | Shared libraries used by pages |
## Storage
All preferences are stored via `browser.storage.local`. The keys and default values are defined in `options/mzta-options-default.js` (`prefs_default` export). Custom prompts and custom placeholders are stored separately in storage under their own keys.
### Per-Message Data Storage
Per-message data (summaries, spam reports, translations) is stored via `js/mzta-storage.js` (`taStorage` class). Each record is keyed by `msg:<headerMessageId>` in `messenger.storage.local` and follows schema version 1. Records contain optional fields: `summary`, `spam`, `translation`, plus metadata (`v`, `ts`). The `taStorage` class provides typed read/write/delete methods per field, automatic record cleanup when all fields are removed, and age-based cleanup.
`js/mzta-summarystore.js` (`taSummaryStore` class) wraps `taStorage` for summary-specific operations: load/save/remove summaries, track in-flight generation state via `browser.storage.session`, enforce a 100-entry cache limit with oldest-first truncation, and store error states.
`js/mzta-translationstore.js` (`taTranslationStore` class) wraps `taStorage` for translation-specific operations: load/save/remove translations, track in-flight generation state via `browser.storage.session`, enforce a 100-entry cache limit with oldest-first truncation, and store error states. Each translation record stores `translated_text`, `lang`, and optional error information.

203
claude-spec/02-prompts.md Normal file
View file

@ -0,0 +1,203 @@
# Prompts System
## Overview
Prompts are the core user-facing feature of ThunderAI. Each prompt defines an AI instruction and how it behaves. There are two kinds:
- **Built-in prompts** — defined in `js/mzta-prompts.js`
- **Custom prompts** — created by the user and stored in `browser.storage.local`
## Prompt Properties
### Base Properties (built-in only)
| Property | Type | Description |
|----------|------|-------------|
| `id` | string | Unique identifier |
| `name` | string | `__MSG_key__` i18n reference or plain text |
| `prompt` | string | The prompt template text (may contain `{%placeholder%}` tokens) |
| `type` | number | `0` = always visible, `1` = reading email only, `2` = composing only |
| `action` | number | `0` = close, `1` = reply (open compose), `2` = substitute text in-place |
| `need_selected` | number | `0` = use full message body, `1` = requires text selection |
| `need_signature` | number | `0` = no signature, `1` = include signature |
| `need_custom_text` | number | `0` = no custom input, `1` = show custom text input field |
| `define_response_lang` | number | `0` = no language hint, `1` = append response language instruction |
| `use_diff_viewer` | number | `0` = normal output, `1` = show diff viewer (ChatGPT Web only) |
### User Properties (stored per-prompt in storage)
| Property | Type | Description |
|----------|------|-------------|
| `enabled` | number | `0` = hidden, `1` = shown in menus |
| `position_display` | number | Sort order for the popup menu in reading view |
| `position_compose` | number | Sort order for the popup menu in compose view |
| `position_context` | number | Sort order for the context menu |
| `show_in` | string | `"popup"` = popup only, `"context"` = context menu only, `"both"` = both, `"none"` = hidden from all menus. Default: `"popup"` for default/custom prompts, `"both"` for special prompts |
| `custom_icon` | string | Filename (with extension) of an icon in `images/context_menu/custom/` used as the context-menu icon. Empty string = no icon. Only used for non-special prompts (special prompts use their hard-coded icons in `specialPromptToContextMenuID`). Selectable from a dropdown on the Menu Order page, context-menu tab. |
### Per-Prompt API Override Properties
Each prompt can override the global API connection. These mirror the keys in `integration_options_config` and `prefs_default`:
| Property | Description |
|----------|-------------|
| `connection_type` | Override API type for this prompt |
| `chatgpt_web_model` | Override ChatGPT Web model |
| `chatgpt_web_project` | Override ChatGPT Web project |
| `chatgpt_web_custom_gpt` | Override custom GPT |
| All `chatgpt_*`, `ollama_*`, `openai_comp_*`, `google_gemini_*`, `anthropic_*` keys | Override specific API settings |
## Special Prompts
Some prompts trigger additional Thunderbird actions beyond just sending text to the AI. They are identified by their `id`:
| ID | Feature |
|----|---------|
| `add_tags` | Auto-tag the email after AI response |
| `spamfilter` | Classify as spam and optionally move email |
| `summarize` | Summarize email content |
| `get_calendar_event` | Extract and create a calendar event |
| `get_task` | Extract and create a task |
| `translate` | Translate email content into a target language |
These special prompts can have their own dedicated API integration settings (configured in the Options page). The list of these special prompts is in `options/mzta-options-default.js` as `special_prompts_with_integration`.
## Menu System
### Popup Menu
- Displays prompts filtered by `show_in` (`"popup"` or `"both"`) and by tab context (`type` property: reading view shows types `0`+`1`, compose view shows types `0`+`2`)
- Ordering: always position-based using `position_display` (reading view) or `position_compose` (compose view). Alphabetical ordering has been removed
- Special prompts retain their colored background (CSS class `special_prompt`) in the popup based on `is_special == "1"`
### Context Menu
- Dynamically built from all prompts with `show_in` set to `"context"` or `"both"`, filtered to reading types only (`type` 0 or 1)
- Appears as a "ThunderAI" submenu in the `message_list` context
- Ordering: position-based using `position_context` (fallback to alphabetical only when positions are equal)
- Special prompts (add_tags, spamfilter, summarize, translate) route through `processEmails()` for batch processing; regular prompts execute via `menus.executeMenuAction()`
- Icons: special prompts use dedicated icons (defined in `contextMenuIconsPath`); all other prompts use the addon icon (`images/icon-32.png`)
- Add Tags in context menu assigns tags automatically (`addTagsAuto: true`), while in the popup it shows the interactive tag selection form
### Menu Order Page (`pages/menu_order/`)
Dedicated page for reordering, enabling, and disabling menu items across both the popup and the context menu. Opened from the options page via the "Menu Order" button.
**UI layout** — two side-by-side panels:
- **Popup Menu panel**: sub-tabs for "Reading" / "Composing" switch the list between `position_display` / `position_compose` ordering and between the allowed types (`0`+`1` vs `0`+`2`)
- **Context Menu panel**: single list ordered by `position_context`. Items with `type: "2"` (composing-only) are never shown here
Each list has two sections:
- **Visible items**: active for the menu (`show_in` includes the menu), draggable to reorder
- **Hidden items**: inactive for the menu (`show_in` excludes the menu), sorted alphabetically, not draggable
**Toggle coordination** — flipping the checkbox updates the prompt's `show_in` with four-state logic:
- Popup ON: `"none"``"popup"`, `"context"``"both"`
- Popup OFF: `"popup"``"none"`, `"both"``"context"`
- Context ON: `"none"``"context"`, `"popup"``"both"`
- Context OFF: `"context"``"none"`, `"both"``"popup"`
**Drag and drop** — native HTML5 DnD assigns sequential position numbers (1, 2, 3, ...) to `position_display`, `position_compose`, or `position_context` depending on which list is being sorted.
**Exclusions from the UI** (preserved on save so data is not lost):
- Prompts with `enabled === 0` (disabled)
- Special prompts whose base definition has `show_in: "none"` (internal prompts like `prompt_summarize_email_template` and `prompt_summarize_email_separator`) — retrieved via `getHiddenSpecialPromptIds()`
- Special prompts whose feature is not active — retrieved from background via `get_active_special_ids` message, which calls `getActiveSpecialPromptsIDs()` with current prefs and `_sparks_presence`
**Cross-tab reload** — the page listens on `browser.storage.onChanged` for changes to `_default_prompts_properties`, `_custom_prompt`, or `_special_prompts`. When one of those keys changes (e.g. user saves from the Custom Prompts page in another tab), the page reloads its data with a 200ms debounce. Any unsaved local changes are discarded to avoid overwriting the other page's work.
**Save flow**:
1. Re-concat preserved prompts (disabled + hidden-specials + inactive-feature specials) with the UI-visible prompts
2. Split by `is_default` / `is_special` and call `setDefaultPromptsProperties()`, `setCustomPrompts()`, `setSpecialPrompts()`
3. Send `reload_menus` to the background to rebuild both menus
### Alphabetic-to-Position Migration
The `dynamic_menu_order_alphabet` preference (previously a user-facing option) has been retired and removed from the UI, but the key still exists in storage as a one-shot migration flag. At every background startup, `migrateMenuOrderAlphabetic()` in `js/mzta-prompts.js` runs:
1. Reads `dynamic_menu_order_alphabet` (defaults to `true` if unset)
2. If `true`: sorts all visible prompts with special prompts first (alphabetically), then the rest (alphabetically), and assigns sequential `position_display` = `position_compose` = `position_context` numbers. Hidden special prompts are preserved untouched.
3. Persists the new positions via `setDefaultPromptsProperties` / `setCustomPrompts` / `setSpecialPrompts`
4. Sets `dynamic_menu_order_alphabet = false` in sync storage so the migration does not run again
This ensures existing users upgrading from the previous alphabetical-default behaviour get the same visible ordering on first run, while subsequent launches keep whatever custom ordering the user has set.
### Special Prompt Visibility Dependencies
`getActiveSpecialPromptsIDs()` in `js/mzta-utils.js` maps feature prefs to active special prompt IDs. Notable dependency:
- `prompt_get_calendar_event_from_clipboard` is emitted only if **both** `get_calendar_event` and `get_calendar_event_from_clipboard` are active. If `get_calendar_event` is off, neither calendar prompt is shown regardless of the clipboard pref.
### Summarize: Dual-Mode Prompt System
The summarize feature uses two distinct prompt pathways:
**Context Menu Summarize** (right-click on messages in message list):
- Activated via the `summarize` context menu item, controlled by the `summarize` feature flag
- Uses 3 special prompts stored in `specialPrompts`:
- `prompt_summarize` — the main instruction prompt for the LLM
- `prompt_summarize_email_template` — template for formatting each email's content
- `prompt_summarize_email_separator` — separator text between multiple emails
- Supports multi-email summarization: each selected message is formatted with the email template, joined by the separator, then prepended with the instruction prompt
- All 3 prompts support placeholder autocomplete (`{%placeholder%}` syntax)
- Result is displayed via `openChatGPT()` in the standard chat output window (not inline)
- Default prompt texts are stored as i18n keys: `prompt_summarize_full_text`, `prompt_summarize_email_template_full_text`, `prompt_summarize_email_separator_full_text`
**Inline Summary on Message Display** (automatic or manual per `summarize_auto` pref):
- Uses the same 3 special prompts as webchat mode, via `taPromptUtils.buildSummaryPrompt()` in `js/mzta-utils-prompt.js`
- Does **not** support `chatgpt_web` connection type (shows error if configured)
- Result is rendered as a styled banner at the top of the message body via `mzta-compose-script.js`
- Banner includes a refresh button (↻) to regenerate the summary
- Cached per-message via `taSummaryStore` / `taStorage` (max 100 entries)
**Unified Prompt Building** — `taPromptUtils.buildSummaryPrompt(messageDataArray)`:
- All summary paths (inline, webchat single, webchat multi) use this single method
- Accepts an array of `{ message, fullMessage }` entries
- Returns `{ promptText, promptInfo }` where `promptInfo` is the `prompt_summarize` prompt object
### Translate: Inline-Only Prompt System
The translate feature uses a single special prompt (`prompt_translate_this`) for translating emails. Translation always renders inline (no webchat mode).
**Inline Translation on Message Display** (controlled by `translate_auto` pref):
- Uses a single special prompt: `prompt_translate_this`
- The prompt uses placeholders (`{%mail_subject%}`, `{%mail_html_body%}`, `{%thunderai_translate_lang%}`, `{%thunderai_translate_exclude_lang%}`) resolved via the standard placeholder system
- The AI response is a JSON object: `{ "subject": "...", "body": "...", "status": "1"|"-1" }`
- `status = "1"`: translation completed, subject and body are displayed
- `status = "-1"`: translation skipped (excluded/target language), a "skipped" message is shown
- Target language is determined by `translate_lang` pref, falling back to `default_chatgpt_lang`
- Does **not** support `chatgpt_web` connection type (shows error if configured)
- Result is rendered as a styled banner (green/teal theme) in the message body via `mzta-compose-script.js`
- Banner includes refresh (↻) and delete (×) buttons
- Cached per-message via `taTranslationStore` / `taStorage` (max 100 entries)
- The prompt was originally a regular prompt (`defaultPrompts`) and was moved to `specialPrompts` with `is_special: "1"` and `type: "1"` (reading email only)
**Prompt Building** — `taPromptUtils.buildTranslationPrompt(fullMessage)`:
- Retrieves the `prompt_translate_this` special prompt text
- Resolves placeholders via `placeholdersUtils.getPlaceholdersValues()` + `replacePlaceholders()`
- Returns `{ promptText, promptInfo }`
## Prompt Types Reference
```
type 0 → shown when reading AND composing
type 1 → shown only when reading an email (message display)
type 2 → shown only when composing an email
```
## Action Types Reference
```
action 0 → no output, just close (e.g. for tag/spam actions handled in background)
action 1 → open a reply compose window with AI response
action 2 → replace selected text (or insert) in compose window
```
## Adding a New Built-in Prompt
1. Add the prompt object to the `defaultPrompts` array in `js/mzta-prompts.js`
2. Add the `name` string key to `_locales/en/messages.json`
3. If the prompt text needs a localized string, add it to `_locales/en/messages.json` as well
4. Reference any needed placeholders using `{%placeholder_id%}` syntax in the `prompt` field
## Custom Prompts
Custom prompts are stored in `browser.storage.local` and managed via `pages/customprompts/`. They follow the same property structure as built-in prompts but are created/edited/deleted by the user through the UI. Custom placeholders can also be referenced in custom prompt text.

View file

@ -0,0 +1,79 @@
# Placeholders System
## Overview
Placeholders are dynamic tokens embedded in prompt text that get replaced with real data at runtime (email content, headers, user input, etc.).
**Format:** `{%placeholder_id%}`
Example in a prompt: `"Summarize this email: {%mail_text_body_or_selected%}"`
## Placeholder Properties
| Property | Type | Description |
|----------|------|-------------|
| `id` | string | Unique identifier used in `{%id%}` tokens |
| `name` | string | Display name (i18n `__MSG_key__` or plain text) |
| `default_value` | string | Value used if placeholder cannot be resolved |
| `type` | number | `0` = always, `1` = reading only, `2` = composing only |
| `is_default` | string | `"1"` = built-in (not editable/deletable), `"0"` = custom |
| `is_dynamic` | string | `"0"` = fixed value, `"1"` = dynamic (takes a parameter after `:`) |
| `enabled` | number | `0` = disabled, `1` = enabled |
| `text` | string | Content for custom placeholders only |
## Built-in Placeholders (defined in `js/mzta-placeholders.js`)
| ID | Description | Type |
|----|-------------|------|
| `mail_text_body` | Full plain text of the email | 0 |
| `mail_html_body` | Full HTML of the email | 0 |
| `mail_typed_text` | Text typed so far in compose window | 2 |
| `mail_text_body_or_selected` | Plain text body, or selected text if any | 1 |
| `mail_html_body_or_selected` | HTML body, or selected HTML if any | 1 |
| `mail_selected_text` | Only the selected text | 1 |
| `mail_selected_html` | Only the selected HTML | 1 |
| `mail_subject` | Email subject line | 0 |
| `mail_date` | Email date | 1 |
| `mail_author` | Email sender | 0 |
| `mail_recipients` | Email recipients | 0 |
| `mail_tags` | Current tags on the email | 1 |
| `mail_available_tags` | All available tags in Thunderbird | 1 |
| `identity_name` | Current identity display name | 0 |
| `identity_email` | Current identity email address | 0 |
| `identity_signature` | Current identity signature | 0 |
| `additional_text[id]` | User input field (dynamic, shows input in popup) | 0 |
| `mail_header:name` | Any email header by name (dynamic) | 1 |
| `mail_full_headers` | All mail headers (key: value format, newline-separated) | 1 |
## Dynamic Placeholders
Dynamic placeholders use a colon separator to pass a parameter:
```
{%additional_text:my_field_id%} → shows an input field labelled "my_field_id" in the popup
{%mail_header:x-spam-score%} → fetches the X-Spam-Score header value
```
The `is_dynamic: "1"` property signals this behavior in the placeholder definition.
## Custom Placeholders
Users can define their own placeholders via `pages/customdataplaceholders/`. Custom placeholders:
- Have `is_default: "0"`
- Have a `text` property containing the replacement value
- Are stored in `browser.storage.local`
- Are merged with default placeholders at runtime before prompt processing
## Placeholder Resolution Order
1. Built-in placeholders are defined in `js/mzta-placeholders.js`
2. Custom placeholders are loaded from storage
3. At runtime, `mzta-background.js` gathers email data (via Thunderbird APIs)
4. Each `{%id%}` token in the prompt string is replaced with the resolved value
5. If a value cannot be resolved, `default_value` is used as fallback
## Adding a New Built-in Placeholder
1. Add the object to the `defaultPlaceholders` array in `js/mzta-placeholders.js`
2. Add the `name` i18n key to `_locales/en/messages.json` as `placeholder_<id>` (or choose a descriptive key)
3. Implement the resolution logic in the relevant section of `mzta-background.js`

View file

@ -0,0 +1,119 @@
# API Integrations
## Connection Types
The active AI provider is controlled by the `connection_type` preference. Possible values:
| `connection_type` value | Provider |
|------------------------|----------|
| `chatgpt_web` | ChatGPT Web (no API key, opens browser window) |
| `chatgpt_api` | OpenAI API (ChatGPT via API key) |
| `ollama_api` | Ollama (self-hosted LLM) |
| `openai_comp_api` | OpenAI-compatible API |
| `google_gemini_api` | Google Gemini API |
| `anthropic_api` | Claude (Anthropic) API |
The global default is `chatgpt_web`. Each special prompt (`add_tags`, `spamfilter`, etc.) can independently override this via its own `{prefix}_connection_type` pref.
## Provider Configuration
Each provider has its own settings block in `integration_options_config` (`options/mzta-options-default.js`):
### ChatGPT Web
Controlled via `js/mzta-chatgpt.js`. Opens a browser window to `chatgpt.com`, injects the prompt via DOM automation, and reads back the response. Settings: `chatgpt_web_model`, `chatgpt_web_tempchat`, `chatgpt_web_project`, `chatgpt_web_custom_gpt`, `chatgpt_web_load_wait_time`.
Content script `js/lib/diff.js` is injected into ChatGPT pages for diff-view support.
### OpenAI API (`chatgpt_api`)
- Module: `js/api/openai_responses.js`
- Worker: `js/workers/model-worker-openai_responses.js`
- Settings keys: `chatgpt_api_key`, `chatgpt_model`, `chatgpt_developer_messages`, `chatgpt_temperature`, `chatgpt_store`
### Ollama (`ollama_api`)
- Module: `js/api/ollama.js`
- Worker: `js/workers/model-worker-ollama.js`
- Settings keys: `ollama_host`, `ollama_model`, `ollama_num_ctx`, `ollama_temperature`, `ollama_think`, `ollama_format_json`
- Requires CORS to be configured on the Ollama server
### OpenAI-Compatible (`openai_comp_api`)
- Module: `js/api/openai_comp.js`
- Worker: `js/workers/model-worker-openai_comp.js`
- Settings keys: `openai_comp_host`, `openai_comp_model`, `openai_comp_api_key`, `openai_comp_use_v1`, `openai_comp_chat_name`, `openai_comp_temperature`
- Pre-configured providers: `js/api/openai_comp_configs.js` (DeepSeek, Grok, Mistral, OpenRouter, Perplexity)
### Google Gemini (`google_gemini_api`)
- Module: `js/api/google_gemini.js`
- Worker: `js/workers/model-worker-google_gemini.js`
- Settings keys: `google_gemini_api_key`, `google_gemini_model`, `google_gemini_system_instruction`, `google_gemini_thinking_budget`, `google_gemini_temperature`
### Anthropic / Claude (`anthropic_api`)
- Module: `js/api/anthropic.js`
- Worker: `js/workers/model-worker-anthropic.js`
- Settings keys: `anthropic_api_key`, `anthropic_model`, `anthropic_version`, `anthropic_max_tokens`, `anthropic_system_prompt`, `anthropic_temperature`, `anthropic_extended_thinking_budget`
- **Extended thinking**: when `anthropic_extended_thinking_budget > 0`, the request body adds `thinking: { type: 'enabled', budget_tokens: N }` and **omits** `temperature` (the Claude API forbids setting temperature with extended thinking). Thinking output arrives in the SSE stream as `content_block_delta` events with `delta.type === 'thinking_delta'` and is forwarded to the webchat UI as `newThinkingToken` messages, captured into a `thinkingAccumulator` in the worker and passed on `tokensDone`.
## Thinking output in the webchat UI
Two provider categories emit reasoning/thinking content:
- **Ollama / OpenAI Compatible**: thinking arrives inline in the normal token stream wrapped in `<think>…</think>` tags. `MessagesArea.flushAccumulatingMessage()` strips these blocks from the rendered text and renders them as a `<details class="thinking-block">` prepended to the answer. If an unterminated `<think>` is detected mid-stream, the flush is deferred until the closing tag arrives.
- **Anthropic**: thinking is captured in the worker and posted to the controller as `newThinkingToken`. `MessagesArea` accumulates it and renders the same `<details>` block on final flush.
The global `hide_thinking` pref (default `true`) controls the **initial open/collapsed state** of the thinking block: `true` → collapsed, `false` → open. The user can always toggle by clicking. Thinking content is never discarded. Other providers (Google Gemini, OpenAI Responses, ChatGPT Web) are not affected by this UI logic.
## Configuration Validation
For special prompts (`mzta_specialCommand`), required fields are validated in `initWorker()` (`js/mzta-special-commands.js`) **before** the worker is created. If a required field is empty, an `Error` with `isConfigError = true` is thrown. Validation covers:
| Provider | Required fields |
|----------|----------------|
| `chatgpt_api` | `chatgpt_api_key`, `chatgpt_model` |
| `google_gemini_api` | `google_gemini_api_key`, `google_gemini_model` |
| `ollama_api` | `ollama_host`, `ollama_model` |
| `openai_comp_api` | `openai_comp_host`, `openai_comp_model` |
| `anthropic_api` | `anthropic_api_key`, `anthropic_model`, `anthropic_version` |
Validation is skipped when `use_specific_api = true` (i.e., the prompt's own `api_type` overrides the global setting — credentials come from the prompt config, not global prefs).
The `isConfigError` flag on the thrown error tells callers in `mzta-background.js` to display the error in the panel **without saving it to storage** — so the user can fix settings and retry cleanly.
Feature-specific routing of `isConfigError`:
- `summarize` / `translate` / `spamfilter`: the error is shown in their dedicated panel (summary / translation / spam panel) and **not** persisted to storage.
- `add_tags`: it has **no dedicated panel**, so the error is routed to the **generic error panel** via `showGenericError(errMsg, source)` in `mzta-background.js`, which broadcasts a `showGenericError` message to all tabs. The content script `js/mzta-compose-script.js` renders it as `#mzta-generic-error` inside `#mzta-container`. The panel is dismissible and reusable by any future feature without its own UI.
For regular prompts (`openChatGPT()`), validation still happens inside the listener callback after the API webchat window is created (unchanged behavior).
## Web Worker Pattern
For all API-based providers (everything except ChatGPT Web), the call goes through a Web Worker:
```
mzta-background.js
→ creates new Worker('js/workers/model-worker-<provider>.js')
→ postMessage({ prompt, settings })
→ worker makes HTTP fetch to provider API
→ worker postMessage({ result }) back
→ background handles result
```
This keeps API calls off the main thread and avoids blocking the Thunderbird UI.
## Optional Permissions
API calls require host permissions. These are declared as `optional_permissions` in `manifest.json` and requested at runtime:
- `https://*.chatgpt.com/*` and `https://*.openai.com/*` for ChatGPT
- `https://*.anthropic.com/*` for Claude
- `https://*/*` and `http://*/*` for Ollama and OpenAI-compatible endpoints
## Adding a New Provider
1. Create `js/api/<provider>.js` with the API call logic
2. Create `js/workers/model-worker-<provider>.js` that imports and calls the API module
3. Add a new `connection_type` value constant
4. Add settings keys to `integration_options_config` in `options/mzta-options-default.js`
5. Add UI controls to `options/mzta-options.html` and `options/mzta-options.js`
6. Add the new `connection_type` case to the dispatch logic in `mzta-background.js`
7. Add required host permissions to `manifest.json` optional_permissions
8. Add i18n strings to `_locales/en/messages.json`

161
claude-spec/05-options.md Normal file
View file

@ -0,0 +1,161 @@
# Options & Settings System
## Overview
All extension preferences are stored in `browser.storage.local`. Defaults and the full list of valid keys are defined in `options/mzta-options-default.js`.
## Key Exports from `mzta-options-default.js`
| Export | Description |
|--------|-------------|
| `prefs_default` | All preference keys with their default values |
| `integration_options_config` | Per-provider API settings structure |
| `getDynamicSettingsDefaults(keysFilter)` | Returns per-special-prompt integration defaults |
| `getDynamicSettingValue(prefs, prefix, settingName)` | Reads a prefixed setting for a special prompt |
## Settings Structure
### Global Integration Settings
Stored flat in `prefs_default` with `{provider}_{key}` naming:
```
chatgpt_api_key, chatgpt_model, chatgpt_developer_messages, chatgpt_temperature, chatgpt_store
ollama_host, ollama_model, ollama_num_ctx, ollama_temperature, ollama_think
openai_comp_host, openai_comp_model, openai_comp_api_key, openai_comp_use_v1, openai_comp_chat_name, openai_comp_temperature
google_gemini_api_key, google_gemini_model, google_gemini_system_instruction, google_gemini_thinking_budget, google_gemini_temperature
anthropic_api_key, anthropic_model, anthropic_version, anthropic_max_tokens, anthropic_system_prompt, anthropic_temperature, anthropic_extended_thinking_budget
```
Plus the global connection selector:
```
connection_type (default: 'chatgpt_web')
use_specific_integration (default: false)
```
### Special Prompt Integration Overrides
The 6 special prompts (`add_tags`, `spamfilter`, `summarize`, `get_calendar_event`, `get_task`, `translate`) each get their own `use_specific_integration` and `connection_type` keys:
```
{prefix}_use_specific_integration (default: false)
{prefix}_connection_type (default: 'chatgpt_api')
```
These are generated programmatically at the bottom of `mzta-options-default.js` using `special_prompts_with_integration` array.
### UI & Feature Preferences
| Key | Default | Description |
|-----|---------|-------------|
| `do_debug` | `false` | Enable debug logging |
| `chatgpt_win_height` | `800` | ChatGPT window height |
| `chatgpt_win_width` | `700` | ChatGPT window width |
| `chatgpt_win_top` | `''` | Window top position |
| `chatgpt_win_left` | `''` | Window left position |
| `chatgpt_win_save_position` | `false` | Remember window position |
| `default_chatgpt_lang` | `''` | Force response language |
| `default_sign_name` | `''` | Default signature name |
| `reply_type` | `'reply_all'` | Default reply type |
| `composing_plain_text` | `false` | Use plain text in compose |
| `chatgpt_web_model` | `''` | ChatGPT Web model override |
| `chatgpt_web_tempchat` | `false` | Use temporary chat |
| `chatgpt_web_project` | `''` | ChatGPT Web project |
| `chatgpt_web_custom_gpt` | `''` | Custom GPT URL |
| `chatgpt_web_load_wait_time` | `1000` | Wait time (ms) for ChatGPT page |
| `dynamic_menu_force_enter` | `false` | Force Enter to submit in popup |
| `dynamic_menu_order_alphabet` | `true` | Internal migration flag only; no UI. Set to `false` by `migrateMenuOrderAlphabetic()` on first boot after upgrade to bootstrap position-based ordering. See `claude-spec/02-prompts.md` for details. |
| `placeholders_use_default_value` | `false` | Use placeholder defaults when empty |
| `hide_thinking` | `true` | Controls the initial state of the thinking `<details>` block prepended above the answer: `true` = collapsed by default, `false` = open by default. The user can always toggle with a click; thinking content is never discarded. |
| `max_prompt_length` | `30000` | Max prompt string length |
### Feature Flags
| Key | Default | Description |
|-----|---------|-------------|
| `add_tags` | `false` | Enable auto-tagging feature |
| `add_tags_maxnum` | `3` | Max tags to apply |
| `add_tags_hide_exclusions` | `false` | Hide excluded tags from menu |
| `add_tags_exclusions_exact_match` | `false` | Exact match for exclusions |
| `add_tags_first_uppercase` | `true` | Capitalize first letter of tags |
| `add_tags_force_lang` | `true` | Force language for tags |
| `add_tags_auto` | `false` | Auto-tag on message open |
| `add_tags_auto_force_existing` | `false` | Only use existing tags |
| `add_tags_auto_only_inbox` | `true` | Auto-tag only inbox messages |
| `add_tags_auto_uselist` | `false` | Use tag allow-list |
| `add_tags_auto_uselist_list` | `''` | Tag allow-list content |
| `add_tags_enabled_accounts` | `[]` | Accounts where auto-tag is active |
| `get_calendar_event` | `true` | Enable calendar event extraction |
| `get_calendar_event_from_clipboard` | `false` | Enable calendar from clipboard |
| `get_task` | `true` | Enable task creation |
| `calendar_enforce_timezone` | `false` | Force specific timezone |
| `calendar_timezone` | `''` | Timezone to enforce |
| `calendar_no_selection` | `false` | Skip selection prompt |
| `spamfilter` | `false` | Enable spam filter |
| `spamfilter_threshold` | `70` | Spam confidence threshold (%) |
| `spamfilter_enabled_accounts` | `[]` | Accounts where spam filter is active |
| `spamfilter_show_msg_panel` | `true` | Show info panel on spam detection |
| `summarize` | `false` | Enable email summarization |
| `summarize_auto` | `1` | Auto-summarize mode: `0` = disabled, `1` = manual (show "click to generate" button), `2` = automatic (generate on message open), `3` = generate on email receive (background pre-cache via `onNewMailReceived`, no UI during generation) |
| `summarize_display_mode` | `'inline'` | Where to display summaries: `'inline'` = message pane banner, `'webchat'` = AI chat window. Note: `summarize_auto = 2` and `summarize_auto = 3` always use inline regardless of this setting. |
| `summarize_max_display_length` | `0` | Maximum characters shown in inline summary before truncation. `0` = no limit (show full text). When set, text is truncated at a word boundary and a "See more"/"See less" toggle link is shown. |
| `summarize_strip_formatting` | `false` | Strip HTML and Markdown formatting from AI-generated summaries, showing plain text only. |
| `translate` | `true` | Enable email translation |
| `translate_auto` | `0` | Auto-translate mode: `0` = disabled, `1` = manual (show button), `2` = automatic (translate on message open), `3` = generate on email receive (background pre-cache via `onNewMailReceived`, no UI during generation) |
| `translate_max_display_length` | `0` | Maximum characters shown in inline translation before truncation. `0` = no limit (show full text). When set, text is truncated at a word boundary and a "See more"/"See less" toggle link is shown. |
| `translate_lang` | `''` | Target language for translation. Falls back to `default_chatgpt_lang` if empty. |
### Summarize Settings Page (`pages/summarize/`)
The summarize settings page provides:
1. **Specific integration checkbox** — enables per-feature API override (like other special prompts)
2. **Auto-summarize dropdown** (`summarize_auto`) — three modes:
- `0` (Disabled) — no inline summaries
- `1` (Manual) — shows a "Click to generate summary" button in message display
- `2` (Automatic) — generates summary immediately when message is opened
3. **Display mode dropdown** (`summarize_display_mode`) — controls where summaries are shown:
- `'inline'` — summary banner in the message pane (default)
- `'webchat'` — opens the AI chat window
- Note: `summarize_auto = 2` always generates inline regardless of this setting. Context menu summarize with multiple messages always falls back to webchat.
4. **Max display length** (`summarize_max_display_length`) — number input, limits inline summary text to N characters. `0` = no limit. When truncated, a "See more"/"See less" toggle link is appended.
5. **Strip formatting** (`summarize_strip_formatting`) — checkbox, removes HTML/Markdown formatting from AI summary responses, displaying plain text only. Default: off.
6. **Three editable prompts** (used by context menu summarize and webchat mode):
- Summarize instruction prompt (`prompt_summarize`)
- Email template prompt (`prompt_summarize_email_template`)
- Email separator prompt (`prompt_summarize_email_separator`)
- Each has Save/Reset buttons and placeholder autocomplete
- Default text comes from i18n strings (`prompt_summarize_full_text`, etc.)
### Menu Order Page (`pages/menu_order/`)
Entry point from the options page via the "Menu Order" button (next to "Manage your prompts"). Provides drag-and-drop reordering and toggle-based visibility control for both the popup and the context menu. See `claude-spec/02-prompts.md` ("Menu Order Page") for the full behaviour, data flow, and exclusion rules.
### Translate Settings Page (`pages/translate/`)
The translate settings page provides:
1. **Specific integration checkbox** — enables per-feature API override (like other special prompts)
2. **Auto-translate dropdown** (`translate_auto`) — three modes:
- `0` (Disabled) — no inline translations
- `1` (Manual) — shows a "Get AI Translation" button in message display
- `2` (Automatic) — generates translation immediately when message is opened
3. **Max display length** (`translate_max_display_length`) — number input, limits inline translation text to N characters. `0` = no limit. When truncated, a "See more"/"See less" toggle link is appended.
4. **Target language** (`translate_lang`) — text input for the destination language. If empty, falls back to `default_chatgpt_lang`.
5. **One editable prompt** — the translation instruction prompt (`prompt_translate_this`) with Save/Reset buttons and placeholder autocomplete. Default text comes from i18n string `prompt_translate_this_full_text`.
## Adding a New Preference
1. Add the key and default value to `prefs_default` in `options/mzta-options-default.js`
2. Add UI control to `options/mzta-options.html`
3. Add load/save logic to `options/mzta-options.js`
4. Add i18n label to `_locales/en/messages.json`
5. Read the pref in the relevant module via `browser.storage.local.get()`
## Reading Preferences at Runtime
```javascript
const prefs = await browser.storage.local.get(prefs_default);
// prefs now contains all keys with defaults for any unset values
const myPref = prefs.my_new_pref;
```

View file

@ -0,0 +1,91 @@
# Localization
## Golden Rule
**Only ever modify `_locales/en/messages.json`.**
All other locale files (`de`, `fr`, `it`, `es`, `zh_Hans`, `zh_Hant`, `pl`, `ru`, `pt-br`, `sv`, `el`, `cs`, `hr`, `ja`, `nb_NO`) are managed by translators through [Weblate](https://hosted.weblate.org/). Never edit them manually.
## Message File Format
Each entry in `_locales/en/messages.json` follows the standard WebExtension i18n format:
```json
"key_name": {
"message": "The English text",
"description": "Context for translators explaining where/how this string is used"
}
```
The `description` field is important — it helps Weblate translators understand the context.
## Using Strings in Code
### In JavaScript
```javascript
import { i18n } from './mzta-i18n.js';
const text = i18n('key_name');
// or directly:
const text = browser.i18n.getMessage('key_name');
```
### In HTML
```html
<span data-i18n="key_name"></span>
<!-- or via manifest/attribute references: -->
__MSG_key_name__
```
### In manifest.json
```json
"description": "__MSG_extensionDescription__"
```
## Naming Conventions
| Prefix | Usage |
|--------|-------|
| `menu_*` | Context menu and popup menu labels |
| `prompt_*` | Built-in prompt names |
| `placeholder_*` | Placeholder display names |
| `options_*` | Settings page labels |
| `pages_*` | Feature page labels |
| `error_*` | Error messages |
| `info_*` | Informational messages |
| `btn_*` | Button labels |
## Adding a New String
1. Open `_locales/en/messages.json`
2. Add the new key in alphabetical order within the file (or near related keys)
3. Include both `message` and `description` fields
4. Use the string in code via `browser.i18n.getMessage('key_name')` or `__MSG_key_name__`
Example:
```json
"my_new_feature_label": {
"message": "My New Feature",
"description": "Label for the new feature button in the options page"
}
```
## Supported Languages (16)
| Code | Language |
|------|----------|
| `en` | English (source) |
| `de` | German |
| `es` | Spanish |
| `fr` | French |
| `it` | Italian |
| `pl` | Polish |
| `ru` | Russian |
| `pt-br` | Brazilian Portuguese |
| `sv` | Swedish |
| `el` | Greek |
| `cs` | Czech |
| `hr` | Croatian |
| `ja` | Japanese |
| `nb_NO` | Norwegian Bokmål |
| `zh_Hans` | Chinese Simplified |
| `zh_Hant` | Chinese Traditional |

View file

@ -0,0 +1,398 @@
# Thunderbird WebExtensions Development Guidelines
> **Purpose:** This file provides operative guidelines for Claude when helping develop or modify ThunderAI. These rules override general AI assistant behavior and must be followed strictly.
## ThunderAI-Specific Context
- ThunderAI uses **Manifest Version 2** — do not suggest or apply any MV3 migration.
- No build tools, no transpilation, no npm — plain ES6 modules loaded directly.
- The manifest already uses `browser_specific_settings` (not `applications`).
- All module imports use relative paths with `.js` extension.
- The `mzta-` prefix is used for all core module filenames.
---
## Important Guidelines for AI Assistants
### 1. Always use `browser_specific_settings` in manifest.json
The `applications` manifest entry is deprecated. Always use `browser_specific_settings`:
```json
{
"manifest_version": 2,
"name": "ThunderAI",
"browser_specific_settings": {
"gecko": {
"id": "thunderai@micz.it",
"strict_min_version": "140.0"
}
}
}
```
### 2. Do not guess APIs by using Try-Catch
A widespread antipattern in AI-generated Thunderbird extensions:
```javascript
// WRONG - Never do this!
try {
await browser.someApi.method({ guessedParam: value });
} catch (e) {
try {
await browser.someApi.method({ differentGuess: value });
} catch (e2) {
// Giving up silently — this makes debugging impossible
}
}
```
**Why this is harmful:**
- Makes code unmaintainable
- Hides real errors from developers
- Makes debugging extremely difficult
**The correct approach:**
1. Read the API documentation FIRST
2. Use the exact parameter names and types specified
3. Only use try-catch for expected error conditions with proper handling
4. Never suppress errors without logging or handling them
### 3. Do not use Experiments unnecessarily
```javascript
// WRONG - Using Experiment when standard API exists
// Don't use Experiment just because you found example code using it
// RIGHT - Check if standard API can do it first
const folders = await browser.folders.query({ name: "Inbox" });
```
### 4. Handle file storage correctly
```javascript
// WRONG - Trying to use raw filesystem APIs
const fs = require('fs'); // Not available!
// RIGHT - Use storage.local with File objects
const file = new File([content], "data.txt", { type: "text/plain" });
await browser.storage.local.set({ file });
```
### 5. Do not use async listeners for the runtime.onMessage listener
See https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage
### 6. Parse vCard, vTodo, vEvent and iCal strings using a 3rd party library
Follow https://webextension-api.thunderbird.net/en/mv2/guides/vcard.html to parse vCard, vEvent and vTodo strings.
### 7. Parse Mailbox Strings using messengerUtilities
Extract email addresses from mailbox strings like "John Doe <john@example.com>":
```javascript
const parsed = await browser.messengerUtilities.parseMailboxString(
"John Doe <john@example.com>, Jane <jane@example.com>"
);
// Result:
// [
// { name: "John Doe", email: "john@example.com" },
// { name: "Jane", email: "jane@example.com" }
// ]
// Extract just emails:
const emails = parsed.map(p => p.email);
```
**Documentation:** https://webextension-api.thunderbird.net/en/mv2/messengerUtilities.html
**Options:**
- `preserveGroups`: Keep grouped hierarchies
- `expandMailingLists`: Expand Thunderbird mailing lists (requires `addressBook` permission)
### 8. Set correct `strict_min_version` entry
Make sure `manifest.json` has a `strict_min_version` entry matching the used functions. If a function added in Thunderbird 137 is used, it must be set to `137.0` or higher.
### 9. Always use background type "module"
Always use `type: "module"` for background scripts. This allows use of the `import` directive for ES6 modules, and non-ES6 libraries can still be loaded via the `scripts` array:
```json
// RIGHT - Always use type: "module"
"background": {
"scripts": ["lib/some-non-ES6-lib.js", "background.js"],
"type": "module"
}
```
Then in `background.js`, import libraries explicitly:
```javascript
// Import ES6 module with default export
import ICAL from "./lib/ical.js";
// Import ES6 module with named exports
import { someFunction, someConstant } from "./lib/somemodule.js";
```
### 10. Verify API return types — do not assume array access
Many Thunderbird APIs return wrapped objects, not direct arrays. Always verify the return type in the documentation before accessing the data.
**Common pitfall — MessageList:**
```javascript
// WRONG - getDisplayedMessages() returns MessageList, not an array
const [message] = await browser.messageDisplay.getDisplayedMessages(tabId);
// RIGHT - MessageList has a .messages array property
const { messages: [message] } = await browser.messageDisplay.getDisplayedMessages(tabId);
```
**Common pitfall — HeadersDictionary:**
```javascript
// WRONG - headers might not exist or might not be an array
let returnPath = headers["Return-Path"];
// RIGHT - keys are lowercase, values are always arrays
const returnPathArray = headers["return-path"];
const returnPath = returnPathArray?.[0] ?? null;
```
**APIs that return wrapped objects (NOT direct arrays):**
| API | Returns | Access Pattern |
|-----|---------|----------------|
| `messageDisplay.getDisplayedMessages()` | `MessageList` | `result.messages[0]` |
| `messages.list()` | `MessageList` | `result.messages[0]` |
| `messages.query()` | `MessageList` | `result.messages[0]` |
| `messages.getHeaders()` | `HeadersDictionary` | `result["header-name"][0]` |
| `messages.getFull()` | `MessagePart` | `result.headers["header-name"][0]` |
**APIs that return direct arrays:**
| API | Returns | Access Pattern |
|-----|---------|----------------|
| `tabs.query()` | array of Tab | `result[0]` |
| `mailTabs.query()` | array of MailTab | `result[0]` |
| `addressBooks.list()` | array of AddressBookNode | `result[0]` |
| `contacts.list()` | array of ContactNode | `result[0]` |
| `folders.query()` | array of MailFolder | `result[0]` |
---
## Official API Documentation
**Primary resource:** https://webextension-api.thunderbird.net/en/mv2/
Documentation exists for different channels:
- **Release (mv2):** https://webextension-api.thunderbird.net/en/mv2/
- **ESR (esr-mv2):** https://webextension-api.thunderbird.net/en/esr-mv2/
**Key feature:** Search functionality and cross-references between types and functions.
---
## Understanding Thunderbird Release Channels
### Standard Release Channel (Monthly)
- Update cadence: ~4 weeks
- A new major version with each release (`147.0`, `148.0`, ...)
- Gets new features and APIs (and bug fixes & security fixes)
### ESR Channel (Extended Support Release)
- Update cadence: 1 major update per year, with lots of versions "missing" in between (`115.*`, `128.*`, `140.*`, `153.*`, ...)
- Receives bug fixes & security fixes on regular basis alongside the major monthly releases, but as minor releases (`140.1`, `140.2`, ...)
- No new features or APIs
### For ThunderAI
- Target the Release channel for standard API usage.
- Target the ESR channel for add-ons relying on Experiment APIs. Targeting the Release channel with Experiments is acceptable *only* when the developer can guarantee required monthly updates.
---
## Experiment APIs
### What Are Experiment APIs?
Experiment APIs allow add-ons to access Thunderbird's core internals directly. They have full access to modify everything in Thunderbird.
### Critical Rules for Experiments
**1. Avoid Experiments Unless Absolutely Necessary**
- Standard WebExtension APIs should always be your first choice
- Only use Experiments when standard APIs genuinely cannot accomplish your goal
**2. Experiments Require Updates for Each Major Version**
- This was manageable with ESR (1x/year)
- Became unsustainable with monthly Release channel (12x/year)
**3. When Suggesting Experiments**
- Only if standard APIs cannot accomplish the core goal
- Developer must explicitly understand the maintenance burden
- **Target ESR channel specifically**
- Reference `esr-mv2` documentation
### Available semi-official Experiment APIs
#### Calendar Experiment API
Use this instead of creating a custom Experiment for calendar interactions.
**Use cases:**
- Reading existing event/task items from Thunderbird's calendar
- Listening for item updates
- Creating/updating/deleting items
**Setup requirements:**
1. Temporarily clone the [webext-experiments](https://github.com/thunderbird/webext-experiments/) repository.
2. Add all `experiment_apis` entries found in `calendar/manifest.json` to the project's `manifest.json`.
3. Copy `calendar/experiments/calendar/` into the project as `experiments/calendar/`. Do not modify these files.
**Note:** Always request iCal format:
```javascript
// Always consult schema first, if this example is still correct
browser.calendar.items.onCreated.addListener(
async (calendarItem) => {
if (calendarItem.type === "task") {
console.log("Task in iCal format:", calendarItem.item);
}
},
{ returnFormat: "ical" }
);
```
### Other Experiment Repositories
- https://github.com/thunderbird/webext-support — Helper APIs and modules
- https://github.com/thunderbird/webext-examples — Example extensions (includes some Experiments)
---
## Native File System Access
### Current Limitations
Native filesystem access is NOT available in Thunderbird WebExtensions.
### Recommended Approach
**For data persistence:**
```javascript
await browser.storage.local.set({ myData: someValue });
const data = await browser.storage.local.get("myData");
```
**For user file input:**
```javascript
const file = new File([content], "filename.txt", { type: "text/plain" });
await browser.storage.local.set({ file });
// Retrieve later
const data = await browser.storage.local.get("file");
console.log(data.file.name);
```
**Important:** File objects can be stored directly in `browser.storage.local` without serialization.
---
## Add-on Review Requirements
**Review policy:** https://thunderbird.github.io/atn-review-policy/
### Key Requirements
**1. No Build Tools**
- Include 3rd party libraries directly (don't use webpack, rollup, etc.)
- Include a `VENDOR.md` file documenting all 3rd party libraries with links to exact versions (not "latest"). Example: https://webextension-api.thunderbird.net/en/mv2/guides/vcard.html
**2. Permissions**
- Only request permissions you actually need
- The `tabs` and `activeTab` permissions are almost never needed in Thunderbird
- Unnecessary permissions may cause rejection during ATN review
---
## Example Repositories
- https://github.com/thunderbird/webext-examples — Official example extensions
- https://github.com/thunderbird/webext-support — Support libraries and helpers
Use these to see proper code structure, learn common patterns, and understand best practices.
---
## Mandatory Checklist Before Providing Code
Before providing any code, verify ALL of these:
- [ ] Consulted official API documentation — do NOT guess methods or parameters
- [ ] NO try-catch blocks for guessing API parameters
- [ ] Used 3rd party libraries or API methods for parsing — minimize manual string parsing or regex
- [ ] Used 3rd party libraries are the most recent stable version
- [ ] Event listeners registered at file scope (NOT inside init function)
- [ ] VENDOR.md includes ALL dependencies with exact version URLs
- [ ] Used `browser_specific_settings` (NOT deprecated `applications`)
- [ ] Included proper error handling
- [ ] Code has comments explaining the approach
- [ ] No hardcoded user-facing strings — use the i18n API (`_locales/en/messages.json` only)
- [ ] Add-on fulfills all requirements in the "Add-on Review Requirements" section
- [ ] All guidelines in "Important Guidelines for AI Assistants" are followed
- [ ] Manifest uses correct `strict_min_version`
- [ ] If using Experiments: manifest has `strict_max_version` targeting current ESR (fetch https://webextension-api.thunderbird.net/en/esr-mv2/ to get the major version, then use format `"<major>.*"`)
If ANY checkbox is unchecked, DO NOT provide the code. Fix it first.
---
## Mandatory 3rd Party Library Audit
For EACH 3rd party library included in the project:
- [ ] Inspect the actual file to determine the export type:
- **ES6 default export:** Look for `export default` → use `import LibName from "./lib/file.js"`
- **ES6 named exports:** Look for `export { name1, name2 }` → use `import { name1, name2 } from "./lib/file.js"`
- **UMD/IIFE (no ES6 exports):** Look for `(function(root, factory)` or assignments to `window`/`globalThis` → load via `scripts` array in manifest
- [ ] Always prefer the minified module version
- [ ] Output a library audit table:
| Library | File | Module Type | Import Statement |
|---------|------|-------------|------------------|
| ical.js | lib/ical.js | ES6 default | `import ICAL from "./lib/ical.js"` |
- [ ] Update VENDOR.md with the correct file path and version URL
---
## Mandatory API Audit
Before finalizing any code:
- [ ] List all used API methods
- [ ] For EACH API method, fetch its documentation page: `https://webextension-api.thunderbird.net/en/mv2/<api-name>.html`
- [ ] For EACH API method, verify:
- **Parameters:** Correct names and types
- **Return type:** The actual type returned by the Promise
- **Access pattern:** How to extract data from the return value
- **Required permission:** What permission is needed in manifest.json
- [ ] Output an API audit table:
| API Method | Returns | Access Pattern | Required Permission |
|------------|---------|----------------|---------------------|
| `browser.messageDisplay.getDisplayedMessages()` | MessageList | `result.messages[0]` | messagesRead |
| `browser.messages.getHeaders()` | HeadersDictionary | `result["header-name"][0]` | messagesRead |
| `browser.mailTabs.query()` | array of MailTab | `result[0]` | (none) |
| `browser.storage.local.get` | object | `result.keyName` | storage |
| `browser.i18n.getMessage` | string | direct | (none) |
- [ ] Update the permissions entry in manifest.json to include ALL required permissions
---
## Getting Help
- **Developer documentation:** https://developer.thunderbird.net/
- **Support forum:** https://thunderbird.topicbox.com/groups/addons
- **Matrix chat:** #tb-addon-developers:mozilla.org

BIN
images/ai_summary.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

BIN
images/ai_translate.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -7,4 +7,4 @@
<circle r="25" fill="#408ee0" cy="50" cx="25">
<animate begin="-0.5s" values="25;75;25" keyTimes="0;0.5;1" dur="1s" repeatCount="indefinite" attributeName="cx"></animate>
<animate repeatCount="indefinite" dur="1s" keyTimes="0;0.499;0.5;1" calcMode="discrete" values="0;0;1;1" attributeName="fill-opacity"></animate>
</circle><g></g></g><!-- [ldio] generated by https://loading.io --></svg>
</circle><g></g></g><!-- [ldio] generated by https://loading.io --></svg>

Before

Width:  |  Height:  |  Size: 990 B

After

Width:  |  Height:  |  Size: 991 B

Some files were not shown because too many files have changed in this diff Show more