Commit Graph

379 Commits

Author SHA1 Message Date
ef0dd74dc1 fix(ui): preserve messages in non-chat windows while scrolled
All checks were successful
CI Code / Check spelling (pull_request) Successful in 17s
CI Code / Check coding style (pull_request) Successful in 27s
CI Code / Code Coverage (pull_request) Successful in 2m44s
CI Code / Linux (debian) (pull_request) Successful in 4m42s
CI Code / Linux (ubuntu) (pull_request) Successful in 4m57s
CI Code / Linux (arch) (pull_request) Successful in 5m50s
_win_printf used to drop the buffer append and pad render for any window
in paged state, but only WIN_CHAT can recover lost messages via
chatwin_db_history on scroll-down. WIN_MUC, WIN_PRIVATE and WIN_AI have
no such fallback, so incoming and outgoing messages were silently lost
when the user was viewing history. Suppress the buffer/render only for
WIN_CHAT; for the rest, still bump unread_msg but let the message land
in the buffer so it becomes visible on scroll-down.

This also removes the manual paged/unread_msg reset before printing the
user message in cl_ev_send_ai_msg — it was a local workaround for the
same drop and is no longer needed.

The buffer-bottom reset in win_page_down (c167f487) is still required:
it is the only path that clears paged and unread_msg for non-chat
windows when the user scrolls back to the bottom (WIN_SCROLL_REACHED_BOTTOM
is set only on the is_chat DB branch).
2026-05-15 19:46:12 +03:00
9e5dfb14f8 feat(ai): add AI client with multi-provider chat support
All checks were successful
CI Code / Check spelling (push) Successful in 18s
CI Code / Check coding style (push) Successful in 29s
CI Code / Code Coverage (push) Successful in 2m44s
CI Code / Linux (debian) (push) Successful in 4m46s
CI Code / Linux (ubuntu) (push) Successful in 4m59s
CI Code / Linux (arch) (push) Successful in 5m56s
Add an AI client module that integrates with OpenAI-compatible API
providers (OpenAI, Perplexity, and custom endpoints) to provide
AI-assisted chat within CProof. Users can start sessions with /ai start,
send prompts, receive responses in a dedicated AI window, switch between
providers and models, and manage API keys — all with tab-completion.

Providers are configured via /ai set commands with per-provider API keys,
endpoints, default models, and custom settings. Two default providers
(openai, perplexity) are seeded on first use. Provider state persists in
[ai/<name>] sections of the preferences keyfile with automatic migration
from the previous flat-key format.

The /ai command integrates into the existing command system with 8
subcommands covering provider management, session lifecycle, model
fetching, and conversation clearing. Autocomplete uses the standard
flat prefix-matching chain for reliable tab-completion at every nesting
level. A new ProfAiWin window type is added to the window system.

Architecture:

Async design: HTTP requests run on a background thread (pthread) to avoid blocking the ncurses UI loop; results are displayed on the main thread via direct function calls
Thread safety: AIProvider and AISession use atomic ref-counting and mutex-protected session state; the request thread snapshots all session data before making the HTTP call
Window validation: wins_ai_exists() prevents use-after-free when the user closes the AI window during an in-flight HTTP request (~60s)
Privacy: store:false is sent with every request to prevent providers from persisting conversations or using them for training
Response size limit: 10MB cap with immediate curl abort via CURL_WRITEFUNC_ERROR to prevent OOM
JSON parsing uses unified helpers for both chat responses and error
envelopes with consistent escape decoding. The response parser tries
Perplexity /v1/responses "text" field first, then falls back to OpenAI
"content". Error parsing extracts provider error.message from the
standard envelope format. Model parsing handles multiple API response
formats (OpenAI list, Perplexity, array) including edge cases.

Tests include 470+ lines of unit tests covering provider management,
session lifecycle, JSON parsing (multiple formats), autocomplete cycling,
and error handling, plus functional tests for /ai command dispatch.
A stub_ai.c module isolates unit tests from UI dependencies.
2026-05-15 02:21:54 +00:00
f4405d114a Add unit tests for forced encryption check function
All checks were successful
CI / Check coding style (pull_request) Successful in 35s
CI / Check spelling (pull_request) Successful in 18s
CI / Linux (debian) (pull_request) Successful in 10m28s
CI / Linux (ubuntu) (pull_request) Successful in 10m51s
CI / Linux (arch) (pull_request) Successful in 13m17s
CI / Check spelling (push) Successful in 17s
CI / Check coding style (push) Successful in 33s
CI / Linux (arch) (push) Successful in 12m53s
CI / Linux (ubuntu) (push) Successful in 12m56s
CI / Linux (debian) (push) Successful in 13m4s
2025-08-27 16:48:27 +02:00
442bfb6ce1 feat: Add /force-encryption command and update message handling
All checks were successful
CI / Check spelling (pull_request) Successful in 18s
CI / Check coding style (pull_request) Successful in 34s
CI / Linux (ubuntu) (pull_request) Successful in 14m5s
CI / Linux (debian) (pull_request) Successful in 14m5s
CI / Linux (arch) (pull_request) Successful in 14m53s
Implement /force-encryption command to configure forced encryption
settings with on|off and policy resend-to-confirm|block options.

The changes enhance user experience by clarifying encryption requirements
and providing actionable commands. Users can now press Enter again to
confirm unencrypted messages in resend-to-confirm mode.
2025-08-25 21:11:27 +02:00
7d1e1c726d fix: Remove unnecessary theme_init call (mem leak)
Simple `ui_resize` is sufficient for rerendering all the elements.
Other calls create complexity, slow down the applications and even introduce mem leaks.

`ui_resize` technique is already used widely, including `cmd_editor` case.

Fixes #4
2025-06-24 15:10:26 +02:00
Michael Vetter
07dfeec816 Release 0.15.0 2025-03-27 20:06:38 +01:00
Steffen Jaeckel
83a4165d92 plugins_(on|pre) API now maybe returns NULL.
Instead of always returning a `strdup()`'ed version, maybe return NULL and
handle this in the calling code.

This is still not true for `plugins_pre_chat_message_display()`, where we
return the passed `messag` in case there are no plugins, since this would
require a bigger refactor of more parts.

This also
* merges the implementation of `sv_ev_incoming_private_message()` and
  `sv_ev_delayed_private_message()`, since they differed only by a single
  line.
* untangles the `#ifdef` mess in `cl_ev_send_muc_msg_corrected()`.

Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
2025-03-12 10:15:35 +01:00
Steffen Jaeckel
95c2199ca2 Some more memory improvements
* Less leaks
* Less allocations

Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
2025-03-12 10:09:41 +01:00
Hanspeter Portner
cb395b7c09 Make muc_nick return a const char* const
In the documentation of the `muc_nick` function we can read:

> The nickname is owned by the chat room and should not be modified or freed

We should reflect that in the return type and `strdup` the value for the
plugin API.

Fixes: https://github.com/profanity-im/profanity/issues/2013
2025-01-26 18:16:14 +01:00
Steffen Jaeckel
848acdd1fa Improve const correctness
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2024-06-19 16:01:46 +02:00
Michael Vetter
569e37f018 Update copyright to 2024 2024-01-22 16:03:48 +01:00
Steffen Jaeckel
f458d6ebdf Fix when feature discovery is finished
Feature discovery was marked as finished once we received a reply to the
initial request. The discovery mechanism allows to delegate the real
feature discovery to another service running on different domain and those
requests are created dynamically.

This was another instance causing the warning message described in #1940

Fixes #1940 (once more)

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-12-28 19:21:27 +01:00
Steffen Jaeckel
b4c088232e Improve const correctness
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-12-12 18:27:09 +01:00
Steffen Jaeckel
bac24601da Introduce equals_our_barejid()
Instead of always repeating the same pattern, introduce a helper function.

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-12-12 18:27:02 +01:00
Steffen Jaeckel
835ea397ac Tidy up some code
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-12-12 18:26:21 +01:00
Steffen Jaeckel
847a86de50 add connection_get_jid()
Use a singleton `Jid` inside the connection instead of always re-creating
a `Jid` from the same string.

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-12-12 18:26:21 +01:00
John Hernandez
be42ffcee9 Fix crash on quick /reconnect now usage (double free)
Check connection state before reconnection.

Fix #1894 https://github.com/profanity-im/profanity/issues/1894
2023-10-15 23:23:01 +02:00
Steffen Jaeckel
2b29d1baf3 Fix some glib nullptr-check warning messages
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-10-04 17:02:10 +02:00
Michael Vetter
122434a276 ox: correctly recognize ox encrypted carbons
and dont display them as legacy pgp encrypted messages.
This was forgotten in 2c94ee5a8.

Fix https://github.com/profanity-im/profanity/issues/1875
2023-08-25 08:24:53 +02:00
John Hernandez
865a056315 Cleanup g_strfreev() to auto_gcharv
Include some additional minor cleanups
2023-07-13 17:05:07 +02:00
John Hernandez
029f1caa52 Cleanup jid_destroy to auto_jid
Remove unused variables
Apply minor cleanups
2023-07-13 17:05:07 +02:00
John Hernandez
8304ac86ff g_free() to auto_gfree, introduce auto_guchar
Fix 11 potential mem leaks in theme.c
2023-07-13 17:04:59 +02:00
John Hernandez
e1d137f4e6 Change char->free to auto_char char for autocleanup
Replace `gchar` and `g_free` to `auto_gchar`
Correct certain  `char` functions/variables to `gchar`

Related to #1819.

Edited by @jubalh.
2023-07-11 13:26:37 +02:00
John Hernandez
4a70f5f513 Cleanup char* to auto_gchar gchar* for prefs_get_string
Necessity explained in #1819
2023-07-03 16:06:27 +02:00
Michael Vetter
ea35a4ceb0 Merge branch 'master' into cleanup/gchar-char 2023-05-11 08:45:46 +02:00
Steffen Jaeckel
8cd53acfd7 fix /reconnect now
This fixes #1846
Issue introduced by a0aa26b6fa

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-05-10 18:12:11 +02:00
Steffen Jaeckel
08d68d329b more auto_char
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-05-10 18:08:09 +02:00
Steffen Jaeckel
7d9c3c1b32 fix "window NULL issue" (hopefully)
There were multiple reports where after a reconnect the window of the
MUC that was last opened, was empty.

`muc_join()` creates an instance of a MUC, `presence_join_room()` works
with this instance. Therefore the instance has to exist before working on
it.

I'm not sure if this really fixes the issue, but at least it didn't
happen anymore after I applied this modification.
I can't remember how I stumbled over this, either while looking at debug
logs or while looking at Valgrind output while a reconnect happened, but
something went wrong. Then I came to the conclusion that this may fix
the issue and for now it did ... maybe it comes back, then my RCA was
wrong.

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-05-10 17:51:52 +02:00
John Hernandez
7f3fca2bd0 Cleanup: gchar as gchar instead of char
Use gchar instead of char in most of the cases where gchar is intended.

Reason: improve compatibility and stability. Issue #1819

Minor refactoring.
2023-05-04 16:15:09 +02:00
John Hernandez
96ddb2399e Add logging consistency
Since MUC private messages are not logged by design,
part where this logging happening is removed to add consistency.

Add explanation in comment.
2023-04-18 18:19:47 +02:00
MarcoPolo-PasTonMolo
ce688f6737 Fix empty window after reconnect
Sometimes after a reconnect the current window would get cleared. This
was a deliberate change to fix the profanity window looking all garbled
up after providing the passphrase for a gpg key using pinentry-curses.

Fixes https://github.com/profanity-im/profanity/issues/1556
2023-04-02 21:53:12 +03:00
John Hernandez
99c9f150f6 Fix PGP
Fix of PGP and potentially other encryption methods by calling correct function that would initiate them in case if someone writes.
2023-03-31 12:30:51 +02:00
Michael Vetter
3adc399da0 Update copyright year 2023-01-10 10:37:25 +01:00
Michael Vetter
3bdc14dbcf Merge MAM improvements from #1724
I think this PR already solves and improves the MAM situation a lot.

What's @MarcoPolo-PasTonMolo still wanted to do in this branch is:
* MAM for mucs
* Check if url and quotes autocompletion works fine
* Check if the api still works fine
* Resolve conflicts

Conflicts are solved with this commit.

MAM for mucs can be another feature PR.

The rest we can check while being on master. And more people can help
testing.
2022-10-21 13:30:43 +02:00
Marouane L
f934c5b59f Add vCard support
Only nicknames, photos, birthdays, addresses, telephone numbers, emails,
JIDs, titles, roles, notes, and URLs are supported

Due to the synopsis array not having enough space, `/vcard photo
open-self` and `/vcard photo save-self` are not documented properly in
the synopsis section of the `/vcard` command, but they are documented in
the arguments section

Fixed memory leak in vcard autocomplete (thanks to debXwoody)
2022-10-18 23:24:30 +01:00
MarcoPolo-PasTonMolo
a704838152 Handle late delivery 2022-08-20 22:48:02 +03:00
MarcoPolo-PasTonMolo
72f613a014 Handle MAM when chatwin gets created from incoming message 2022-07-10 12:28:14 +03:00
Michael Vetter
f30999fd51 ox: handle empty message->plain
In case we dont have plain but have body, copy this (like in
_sv_ev_incoming_pgp).
In case we have neither, return.
2022-07-04 16:40:44 +02:00
Michael Vetter
585f68f4f7 Split log.c into log.c and chatlog.c 2022-06-28 20:08:38 +02:00
Michael Vetter
1330ad4e1e Update copyright year 2022-05-09 15:43:33 +02:00
Stefan Ott
8044c82614 Add support for offline MUC notifications 2022-04-23 02:42:23 +02:00
Steffen Jaeckel
7f1f9787cb add profanity-specific CAfile
The profanity-internal mechanism to allow connecting to a server isn't
easily portable to cURL. Therefor introduce a profanity-specific CAfile
which is managed individually and will be configured in libcurl calls.

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2022-03-22 11:44:01 +01:00
Steffen Jaeckel
b28ac09368 a tad more const-correctness
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2022-03-22 11:44:00 +01:00
Michael Vetter
6d1c661e21 Remove banned muc member from member list
If I'm understing everything right the member should be removed here.
muc_members_update() seems to have been writen for the same purpose.

Fix https://github.com/profanity-im/profanity/issues/1594
2022-02-02 21:57:44 +01:00
Steffen Jaeckel
9cf78e59d5 auto-format
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2022-02-01 15:01:28 +01:00
Michael Vetter
46c8245af9 Format new register code correctly 2021-10-13 21:32:44 +02:00
swirl
87d2c95c87 registration: remove auth param and excess functions 2021-08-17 14:09:48 -04:00
swirl
2cc354b6ae fixed some bugs, added some more
- Added JABBER_RAW_CONNECT[ING/ED] connection states
- Added cl_ev_connect_raw and session_connect_raw to conform to normal
connection functions
- Fixed SIGABRT during registration
- Added a check in cmd_register to ensure it's actually connected before
registering--but this will always fail atm
2021-08-17 14:09:48 -04:00
Dmitry Podgorny
afdae6ac02 Reduce copy-paste in sv_ev_roster_received() 2021-07-17 18:12:42 +03:00
Dmitry Podgorny
e7b6051e57 Fix memory leak in accounts_get_login_status() 2021-07-17 18:11:32 +03:00