Skip to content

feat(gateway): add Zulip integration and messaging support - #3335

Open
nicolasembleton wants to merge 4 commits into
NousResearch:mainfrom
nicolasembleton:feat/zulip
Open

feat(gateway): add Zulip integration and messaging support#3335
nicolasembleton wants to merge 4 commits into
NousResearch:mainfrom
nicolasembleton:feat/zulip

Conversation

@nicolasembleton

@nicolasembleton nicolasembleton commented Mar 27, 2026

Copy link
Copy Markdown

What does this PR do?

This PR adds Zulip support to Hermes as a bundled platform plugin under
plugins/platforms/zulip/.

The original branch predated the current platform plugin system and wired Zulip
through several core gateway, CLI, scheduler, and tool files. This update moves
the integration onto the current plugin path: platform registration, setup
metadata, env/YAML configuration, auth validation, adapter construction, cron
delivery metadata, standalone text delivery, and the Zulip search tool now live
with the plugin.

The goal is to keep Zulip support aligned with the current platform architecture
while preserving the adapter behavior that has been tested by real users.

Related Issue

Related to the earlier Zulip PRs:

This PR remains the canonical Zulip candidate per maintainer feedback on this
thread.

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • plugins/platforms/zulip/
    • Adds the Zulip platform plugin, adapter, plugin metadata, standalone sender, setup/config
      hooks, and Zulip search tool.
    • Supports DMs, stream topics, mention/free-response handling, thread/session isolation, topic
      names containing /, media handling, typing/reactions where supported, and edit-based
      streaming.
  • pyproject.toml, uv.lock, tools/lazy_deps.py
    • Adds Zulip as an optional/lazy dependency through the zulip extra.
  • website/docs/user-guide/messaging/zulip.md
    • Adds Zulip setup, configuration, cron delivery, standalone send, search, and streaming docs.
  • website/docs/user-guide/messaging/index.md
    • Lists Zulip in the messaging platform docs.
  • tests/gateway/test_zulip.py
    • Adds gateway/plugin adapter coverage.
  • tests/tools/test_zulip_search_messages.py
    • Adds coverage for Zulip message search behavior.
  • tests/test_project_metadata.py
    • Adds coverage for Zulip dependency/plugin metadata wiring.

This revision also incorporates updates from @slav's patches and @a6patch's
branch work, manually integrated into the plugin structure to keep this PR
reviewable:

  • Current-Hermes compatibility updates.
  • Zulip connected-state checking.
  • Platform registry support with standalone sender behavior.
  • Reconnect compatibility coverage.
  • Zulip message edit capability.
  • edit_message(..., finalize=..., metadata=...) support for gateway streaming.
  • Docs/tests for edit-based Zulip streaming.
  • Cron and standalone delivery validation.

How to Test

  1. Install with the Zulip extra, or with all extras:

    UV_PROJECT_ENVIRONMENT=venv uv sync --locked --extra zulip

    or:

    UV_PROJECT_ENVIRONMENT=venv uv sync --locked --extra all
  2. Configure Zulip credentials and run setup/gateway:

    hermes setup
    hermes gateway
  3. Validate normal gateway behavior from Zulip:

    • Send the bot a DM.
    • Mention the bot in a stream topic.
    • Test a topic containing /, such as some/topics/with/slashes.
    • Attach an image and confirm the agent can see it.
    • Use zulip_search_messages from a Zulip conversation.
  4. Validate standalone send with a configured home channel:

    hermes send --to zulip "Standalone Zulip send smoke"
  5. Validate cron delivery:

    hermes cron create \
      --name zulip-cron-smoke \
      --deliver "zulip:5:Sauve Cloud Status" \
      --repeat 1 \
      --script zulip-cron-smoke.sh \
      --no-agent \
      "every 1d" \
      "Zulip cron smoke"
    
    hermes cron run zulip-cron-smoke
  6. Validate edit-based streaming by enabling both the global/root streaming flag
    and the Zulip platform streaming flag:

    display:
      streaming: true
      platforms:
        zulip:
          streaming: true
  7. Run focused tests:

    pytest tests/gateway/test_zulip.py tests/tools/test_zulip_search_messages.py tests/
    test_project_metadata.py -q

Checklist

Code

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/
    A
  • I've considered cross-platform impact (Windows, macOS) per the [compatibility guide]
    (https://github.com/NousResearch/hermes-agent/blob/main/CONTRIBUTING.md#cross-platform-
    compatibility) — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

Manually validated:

  • Zulip gateway startup and connection.
  • Inbound DM handling.
  • Stream/topic handling.
  • Topics containing /.
  • Thread/session isolation.
  • Zulip message search.
  • Image reception and vision support.
  • Standalone send using the configured Zulip home channel.
  • Cron delivery to Zulip.
  • Edit-in-place streaming.

Example standalone send result:

hermes send --to zulip "Standalone Zulip send smoke"
Sent to zulip home channel (chat_id: 5:Sauve Cloud Status)

Notes / Follow-Ups

Edit-based streaming requires the global/root gateway streaming setting to be
enabled in addition to the Zulip platform setting. Users should also be aware
that Zulip may retain message edit history depending on the organization's Zulip
settings.

Two shared follow-ups were found while testing this PR:

  1. Direct CLI sends to a specific Zulip topic, such as
    hermes send --to "zulip:stream:topic" ..., need one small shared sender fix
    outside of the Zulip plugin. This will be proposed separately after the plugin
    PR lands.

  2. One-shot cron jobs using --repeat 1 can sometimes deliver correctly but
    still print a failure status after completion. This appears to overlap with
    fix: report immediate cron run status for depleted repeat jobs #57689, so it is not included here.

@nicolasembleton
nicolasembleton force-pushed the feat/zulip branch 5 times, most recently from 59d6db9 to ca943ef Compare April 3, 2026 07:59
@punk5736

punk5736 commented Apr 6, 2026

Copy link
Copy Markdown

Interested in this, thanks for submitting.

@nicolasembleton

Copy link
Copy Markdown
Author

Interested in this, thanks for submitting.

Thanks @punk5736 . I've been using it since I published it, and keeping it up-to-date with current Hermes main, so you can try to pull this PR branch and use it as your Hermes see if you find any bugs. There were a few issues after latest version, and I've also added send_voice() so now Hermes can send me summaries for things such as job search summry or news, etc... Super handy. There may be some features that I have not used yet that aren't supported so I would love any feedback if y'all feel like trying it.

@nicolasembleton
nicolasembleton force-pushed the feat/zulip branch 6 times, most recently from 61a0dfa to ecfd939 Compare April 15, 2026 11:10
@nicolasembleton
nicolasembleton force-pushed the feat/zulip branch 2 times, most recently from c96ca9c to 12f5a12 Compare April 22, 2026 07:06
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard labels Apr 22, 2026
@mplorentz

Copy link
Copy Markdown

Thank you for building this! Zulip's interface seems a lot better for managing many long-running conversations with hermes than the other gateways I have tried.

I have deployed this branch on my machine and it is working pretty well. A couple small hiccups:

  • I am deploying hermes in a docker container, and I had to exec into it to manually run source .venv/bin/activate && uv pip install zulip. This is slightly different from the pip install zulip that is mentioned in the docs. Might be worth documenting or maybe the zulip package should be included in the Docker image by default?
  • I am not seeing typing indicators from the bot in Zulip. I checked that I do have typing indicators enabled in my personal settings.

@nicolasembleton

Copy link
Copy Markdown
Author
  • I am deploying hermes in a docker container, and I had to exec into it to manually run source .venv/bin/activate && uv pip install zulip. This is slightly different from the pip install zulip that is mentioned in the docs. Might be worth documenting or maybe the zulip package should be included in the Docker image by default?
  • I am not seeing typing indicators from the bot in Zulip. I checked that I do have typing indicators enabled in my personal settings.

Nice. Thanks for giving it a try and thanks for the feedback. I just realized I hadn't noticed the missing typing indicator 😅 . Let me fix this and see if I can improve the setup flow (or at the very least the documentation)

@slav

slav commented Apr 25, 2026

Copy link
Copy Markdown

Just to add to this. I was having hard time getting hermes to send message to specific, different from current, chat:stream, for example to start a new stream. It said there's a bug and fixed with this code. Code is generated, so could be completely off, but it worked and it started to send messages into different streams as expected.

zulip-stream-topic-send.patch

@alt-glitch alt-glitch mentioned this pull request Apr 27, 2026
@punk5736

punk5736 commented Jul 8, 2026

Copy link
Copy Markdown

@nicolasembleton is the paging for long messages imposed by Zulip? It would be nice if there was a way for them to be continuous, so figured I'd check.

@alt-glitch alt-glitch added the comp/gateway Gateway runner, session dispatch, delivery label Jul 8, 2026
@slav

slav commented Jul 9, 2026

Copy link
Copy Markdown

I'm often requesting agent to create new zulip thread to address something new that comes up, to essentially avoid mixing different things in one context. Makes it very easy to change focus and then come back to where we were. Hermes can do it, but it kept creating temp scripts, etc. So we created a tool to help with that. It allows hermes to send message to any Zulip thread, creating it if it doesn't exist. Makes very easy to split work. I did keep it in zulip-history toolset as didn't want to rename it in case it might break something.

Also, the ability to stream via editing message worked great, but on desktop client for Zulip the message would flash all the time essentially making it unreadable. To address it's possible to use Hermes built-in edit_interval to set update once every 1-2 seconds. Added docs about that.

The patch is based on current PR with Zulip being a plugin.
zulip-docs-and-topic-tool.patch

p.s. Updated patch to fix credentials lookup bug

@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Canonical Zulip candidate per the maintainer thread. Related open alternative: #16541 (earlier second implementation); feature-request issue #49229; closed predecessor #54715. A maintainer should pick this as canonical and close the competing Zulip PR.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for moving the adapter onto the plugin path requested in the maintainer thread; the registration at plugins/platforms/zulip/adapter.py:2425-2456 uses the existing platform hooks cleanly.

Problems

  • plugins/platforms/zulip/adapter.py:939 calls synchronous update_message() inside async edit_message(). Streaming invokes this repeatedly, so a slow Zulip request blocks the gateway event loop. Please offload it with await asyncio.to_thread(...) and cover that path.
  • plugins/platforms/zulip/adapter.py:538-540 directly applies int() to optional ZULIP_CONTEXT_DEPTH. A malformed value aborts adapter construction. The nearby catch-up parser already defaults safely on malformed input at :564-576; apply the same pattern and add a regression test.

Suggested changes

  • Preserve the current SendResult behavior after moving the edit request off-loop.
  • Default invalid context depth to disabled (0) rather than failing gateway startup.

Automated hermes-sweeper review.

Comment thread plugins/platforms/zulip/adapter.py Outdated
Comment thread plugins/platforms/zulip/adapter.py Outdated
@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data labels Jul 12, 2026
@nicolasembleton

Copy link
Copy Markdown
Author

I'm traveling to Berlin ATM but the PR update is ready, will push it tomorrow after I've finished my tests.

@nicolasembleton

Copy link
Copy Markdown
Author

@teknium1 the fixes have been pushed, resynced with upstream, @slav patch is in, and I made small improvements to attachments handling, and checked if we could improve paging following @punk5736 request, but unfortunately it is dependent on Zulip, which is not friendly to larger messages. You can tweak your own Zulip server config to set it to 10k characters but it won't allow more than that.
However, if you do configure it, Hermes will now render better in this latest update and Zulip will page automatically at min(10k, your-current-setting).

@ajtowns ajtowns left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really nice -- I've been trying to figure out how to chat locally and get equations and images nicely inline.

Comment thread plugins/platforms/zulip/adapter.py
Comment thread plugins/platforms/zulip/adapter.py Outdated
Comment thread plugins/platforms/zulip/adapter.py Outdated
@allenkaplan

Copy link
Copy Markdown

This is really nice -- I've been trying to figure out how to chat locally and get equations and images nicely inline.

if non-blocking perhaps we can defer to follow up? or a PR into this worknig set? would be great to see this in asap :D

@nicolasembleton

Copy link
Copy Markdown
Author

Resynced with upstream V0.19:
Hermes Agent v0.19.0 (2026.7.20) · upstream f4df260f · local 7efa0465 (+1 carried commit)

Applied recent comments. Latex (Katex in this case) works:

CleanShot 2026-07-21 at 10 29 12@2x

@nicolasembleton

Copy link
Copy Markdown
Author

Rebased to v0.19.1. @teknium1 please merge when you can :)

Comment thread plugins/platforms/zulip/adapter.py Outdated
@slav

slav commented Aug 3, 2026

Copy link
Copy Markdown

It seems Approve buttons broke (probably due to hermes changes). Here's the short patch to fix them to show again.

From AI describing the patch:

  • Root cause: The gateway passes allow_session to send_exec_approval(), but the Zulip adapter did not accept it, causing a TypeError.
  • User impact: Zulip approval buttons failed to render, forcing users to type /approve manually.
  • Fix: Add allow_session: bool = True to the Zulip adapter method.
  • Default behavior: With allow_session=True, continue showing Once, Session, Always, and Deny as permitted.
  • Restricted behavior: With allow_session=False, show only Once and Deny. Session and Always are intentionally omitted.
  • Permanent approval: With allow_permanent=False, omit Always while retaining Session.

zulip-approval-allow-session.patch

@nicolasembleton

Copy link
Copy Markdown
Author

It seems Approve buttons broke (probably due to hermes changes). Here's the short patch to fix them to show again.

From AI describing the patch:

  • Root cause: The gateway passes allow_session to send_exec_approval(), but the Zulip adapter did not accept it, causing a TypeError.
  • User impact: Zulip approval buttons failed to render, forcing users to type /approve manually.
  • Fix: Add allow_session: bool = True to the Zulip adapter method.
  • Default behavior: With allow_session=True, continue showing Once, Session, Always, and Deny as permitted.
  • Restricted behavior: With allow_session=False, show only Once and Deny. Session and Always are intentionally omitted.
  • Permanent approval: With allow_permanent=False, omit Always while retaining Session.

zulip-approval-allow-session.patch

I did notice this, yes. Let me fix this and thanks for the patch.

@nicolasembleton

Copy link
Copy Markdown
Author

Sorry, forgot to report back but I've been using the latest version since I updated and it's been good to me. :)
Buttons are back, LaTex works on top of KaTex, have some skills to run smoke checks that have proven very effective, so things are getting smoother. Found an issue (via skills) where the Zulip message search was not searching in long messages.

Next update I'll squash all the commits into 1, but meanwhile y'all can see what happened.

@nicolasembleton

nicolasembleton commented Aug 18, 2026

Copy link
Copy Markdown
Author

Rebased to HEAD.

@punk5736

punk5736 commented Aug 18, 2026

Copy link
Copy Markdown

Hey @nicolasembleton, is message-splitting being advertised such that cron jobs can post more than 4000 characters? I am running the latest commit and have a cron job running which truncated output. The cron process did not attempt to split the output across several messages.

Asking hermes to debug the truncation informed me that cron jobs expect splits_long_messages=True if they are going to chunk. A quick search over the diff did not return a match for that.

Thank you once again.

@punk5736

Copy link
Copy Markdown

Hey @nicolasembleton, is message-splitting being advertised such that cron jobs can post more than 4000 characters? I am running the latest commit and have a cron job running which truncated output. The cron process did not attempt to split the output across several messages.

Asking hermes to debug the truncation informed me that cron jobs expect splits_long_messages=True if they are going to chunk. A quick search over the diff did not return a match for that.

Thank you once again.

Hmm, on other cron runs it seems to be sending longer (and complete) messages. For reference, the truncated cron run message ended with: [truncated, full output saved to /data/.hermes/cron/output/<id>.txt].

@nicolasembleton

nicolasembleton commented Aug 20, 2026

Copy link
Copy Markdown
Author

Hey @nicolasembleton, is message-splitting being advertised such that cron jobs can post more than 4000 characters? I am running the latest commit and have a cron job running which truncated output. The cron process did not attempt to split the output across several messages.
Asking hermes to debug the truncation informed me that cron jobs expect splits_long_messages=True if they are going to chunk. A quick search over the diff did not return a match for that.
Thank you once again.

Hmm, on other cron runs it seems to be sending longer (and complete) messages. For reference, the truncated cron run message ended with: [truncated, full output saved to /data/.hermes/cron/output/<id>.txt].

Hey — thanks for flagging this. You were right. @punk5736

Cron has a 4 000-character safety cap for platforms it thinks can't split long messages. Zulip's send() already splits at 10k (that's Zulip's own limit), but we never told cron that. So if the gateway was running, it would cut the message and dump the rest to a file — that's the [truncated, full output saved to …] footer you saw. When cron ran without a live gateway it already sent the full thing, which is why some jobs looked fine and others didn't. No Zulip max-length setting to change on your side.

Fix is a one-liner: advertise splits_long_messages = True, same as Discord / Telegram / Slack.

What Before After
Normal chat, incoming messages, edits, buttons As today Unchanged
Cron, no live gateway Full output, split at 10k Same
Cron via the gateway, under 4k One complete message Same
Cron via the gateway, over 4k Truncated + file footer Full output, split at 10k

For your case: that truncated run should now post in full. If it's over 10k it'll come through as a few messages instead of one short one plus a path.

One thing to watch: a huge dump will now show up as several messages in the topic, not one stub. We still save the file when it's over 4k, we just won't mention it in-channel. And the whole cron body now goes through the $…$ → KaTeX rewrite, so if your logs are full of $ you may want ZULIP_CONVERT_MATH=false. Live chat is untouched.

@punk5736

Copy link
Copy Markdown

@nicolasembleton It seems that cron jobs, when manually triggered, fail to send documents in messages. When the cron is a regular tick, the documents send fine.

Also, when I ad hoc ask hermes to send the same document it produced in a cron run it is able to send it fine.

After asking hermes to analyze this, it responded with:

The cron job did produce the PDF. Hermes then tried to deliver it on a path that refuses attachments.

Two different senders
- Scheduled ticks (source=builtin) go through the live gateway adapter (pid 1). That path can upload MEDIA: files to Zulip.
- Manual fires (cronjob action=run / hermes cron run, source=direct) use _standalone_send_zulip. That function returns immediately if any media is present: "does not support media attachments yet." On that error Hermes drops the digest too, so the topic stays empty.

What do you think?

nicolasembleton and others added 4 commits August 26, 2026 08:32
…#3335)

Add Zulip (cloud or self-hosted) as a supported messaging platform.
Purely additive — no upstream code removed or replaced.

Ships as a platform plugin under plugins/platforms/zulip/ with adapter,
attachments, search, and topic tools, plus docs and tests.

Review follow-ups and post-merge fixes rolled into this commit:
- send_exec_approval accepts allow_session / allow_permanent / smart_denied
- full command in its own message, zform buttons as a follow-up
- platform_hint documents MEDIA paths and Zulip KaTeX markup
- multi-line dollar display math rewritten to fenced math blocks
- convert $...$, \(...\), \[...\], and whole-line $$ to Zulip KaTeX
  (opt out with ZULIP_CONVERT_MATH=false)
- pin Zulip client to 0.9.1
- rejoin multi-chunk replies in search (i/n markers)
- client-scan long messages when FTS misses content in large replies

314 Zulip-related tests passing.

Co-authored-by: Kevin Patch <klp@anaconda.net>
Co-authored-by: Slav Ivanyuk <350987+slav@users.noreply.github.com>
…at 4k

Cron delivery was cutting live-gateway Zulip jobs at 4000 characters because
the adapter never set splits_long_messages. send() already chunks at 10k.
Zulip was missing from MESSAGING_SESSION_SOURCE_IDS, so gateway
sessions never grouped with Mattermost/WhatsApp. Register the
source, brand icon, and messaging intro copy.
Manual hermes cron run and dashboard fires have no live adapter, so
delivery used _standalone_send_zulip, which refused MEDIA files and
dropped the digest with them. Reuse send_document/send_image_file
(throwaway Zulip client, same API as scheduled ticks). A failed
upload is a warning so the text still lands.
@punk5736

Copy link
Copy Markdown

@teknium1 Could this PR get another round of review? I'm daily driving this and would like to get back on the main line.

@nicolasembleton

nicolasembleton commented Aug 26, 2026

Copy link
Copy Markdown
Author

@nicolasembleton It seems that cron jobs, when manually triggered, fail to send documents in messages. When the cron is a regular tick, the documents send fine.

Also, when I ad hoc ask hermes to send the same document it produced in a cron run it is able to send it fine.

After asking hermes to analyze this, it responded with:

The cron job did produce the PDF. Hermes then tried to deliver it on a path that refuses attachments.

Two different senders
- Scheduled ticks (source=builtin) go through the live gateway adapter (pid 1). That path can upload MEDIA: files to Zulip.
- Manual fires (cronjob action=run / hermes cron run, source=direct) use _standalone_send_zulip. That function returns immediately if any media is present: "does not support media attachments yet." On that error Hermes drops the digest too, so the topic stays empty.

What do you think?

Once again, thanks for surfacing good use cases @punk5736. I had not done that yet so this was missed. The zulip integration was explicitly not accepting standalone sends (as in, not directly requested through a live session). Standalone now sends the message text, then the files. If an upload fails, you still get the digest. I added cron-send to my smoke test script and all passed. The only test that did not pass completely is full-text-search in very long messages in large Zulip instances when resources are limited, ingest / search may take time, I'll see if there's something I can do there, but this should not be a problem for the vast majority of users/use-cases.

This update also adds support for Zulip in Desktop UI, the same way other Channels do @teknium1

Note: I also rebased while I was at it.

@punk5736

Copy link
Copy Markdown

@nicolasembleton It seems that cron jobs, when manually triggered, fail to send documents in messages. When the cron is a regular tick, the documents send fine.
Also, when I ad hoc ask hermes to send the same document it produced in a cron run it is able to send it fine.
After asking hermes to analyze this, it responded with:

The cron job did produce the PDF. Hermes then tried to deliver it on a path that refuses attachments.

Two different senders
- Scheduled ticks (source=builtin) go through the live gateway adapter (pid 1). That path can upload MEDIA: files to Zulip.
- Manual fires (cronjob action=run / hermes cron run, source=direct) use _standalone_send_zulip. That function returns immediately if any media is present: "does not support media attachments yet." On that error Hermes drops the digest too, so the topic stays empty.

What do you think?

Once again, thanks for surfacing good use cases @punk5736. I had not done that yet so this was missed. The zulip integration was explicitly not accepting standalone sends (as in, not directly requested through a live session). Standalone now sends the message text, then the files. If an upload fails, you still get the digest. I added cron-send to my smoke test script and all passed. The only test that did not pass completely is full-text-search in very long messages in large Zulip instances when resources are limited, ingest / search may take time, I'll see if there's something I can do there, but this should not be a problem for the vast majority of users/use-cases.

This update also adds support for Zulip in Desktop UI, the same way other Channels do @teknium1

Note: I also rebased while I was at it.

Can confirm that a manually triggered cron now is able to send Zulip messages.

Also confirming that the gateway UI shows Zulip on the channels view. In the configuration view, some of the input fields have placeholders which indicated the environment variable for the field while others have a default (?), example, or basic placeholder text .. Should this be uniform? Possibly to environment variables hints? This is a stray suggestion since I use the Nix + .env configuration mode and was curious what all the environment variable equivalents are for each field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) comp/plugins Plugin system and bundled plugins needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.