Skip to content

Reckless UI features#8630

Open
endothermicdev wants to merge 27 commits intoElementsProject:masterfrom
endothermicdev:reckless-ui-features
Open

Reckless UI features#8630
endothermicdev wants to merge 27 commits intoElementsProject:masterfrom
endothermicdev:reckless-ui-features

Conversation

@endothermicdev
Copy link
Collaborator

@endothermicdev endothermicdev commented Oct 23, 2025

Important

25.12 FREEZE October 27th: Non-bugfix PRs not ready by this date will wait for 26.03.

RC1 is scheduled on November 10th

The final release is scheduled for December 1st.

Checklist

Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes.
  • Documentation has been reviewed and updated as needed.
  • Related issues have been listed and linked, including any that this PR closes.

Addresses several issues raised in #8439. Still working on a few of them.

@endothermicdev endothermicdev added this to the v25.12 milestone Oct 23, 2025
@endothermicdev endothermicdev marked this pull request as ready for review October 31, 2025 19:43
@endothermicdev endothermicdev force-pushed the reckless-ui-features branch 3 times, most recently from b2ccfc0 to 7ab612f Compare November 7, 2025 16:16
@endothermicdev endothermicdev modified the milestones: v25.12, v26.03 Nov 13, 2025
@endothermicdev
Copy link
Collaborator Author

Rebased and updated reckless rpc to handle single argument reckless commands (the new listconfig, listavailable, listinstalled) and handle json objects in the result (listconfig output.)

Copy link
Collaborator

@ShahanaFarooqui ShahanaFarooqui left a comment

Choose a reason for hiding this comment

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

Hi @endothermicdev, thanks for the PR! I am excited to start integrating reckless with these cool new options into the UI soon. In the meantime, here are the results from my testing of reckless.


1. install "backup" Crashes Lightning Node

After running lightning-cli reckless install "backup", it installs the backup plugin but crashes without any error log:

2025-11-14T05:35:08.692Z DEBUG   plugin-recklessrpc: calling: reckless -v --json -l /home/.lightning --network regtest install backup (null)

Restart keeps repeatedly crashing the CLN node:

2025-11-14T05:36:51.578Z DEBUG   plugin-manager: started(798730) /home/.lightning/reckless/backup/backup.py
2025-11-14T05:36:51.752Z INFO    plugin-backup.py: Could not find backup.lock in the lightning-dir
2025-11-14T05:36:52.757Z INFO    plugin-backup.py: Killing process lightningd (798649)

2. install 1ff0ee6 "clnrod" Ignored the Requested Commit

The plugin installed, but the requested commit 1ff0ee6 was not honored.

3. Installing From GitHub URLs Fails

Reckless is unable to detect the plugin from the provided URL.
Examples:

lightning-cli reckless install "https://github.com/nettijoe96/c-lightning-graphql"
lightning-cli reckless install "https://github.com/nettijoe96/c-lightning-graphql/tree/12888f124bbdf9ffe1fbbd3d7cf0286c66184e8e"

4. listinstalled Reckless Plugin Vs RPC Output

The RPC returns only a string array of plugin names, while the standalone reckless plugin returns full metadata (enabled, entrypoint, installed commit, etc.).It would be useful for the RPC to return the richer JSON structure.

5. Improve listavailable Output Format

Currently it returns a simple text array of plugins. But I would suggest switching to JSON objects so manifest metadata can be also added once available (eg. description, entrypoint, default commit, last updated, language, etc.).

6. Should .remote_sources Be Deleted After listavailable?

7. Plugin Search Priority Is Unclear

Proposed priority:

  • Installed plugins (enabled/disabled)
  • Source URL
  • .remote_sources directory

Step to reproduce:

  • Install "summary" plugin
  • Call listavailable which will create .remote_sources directory
  • Call search "summary" will list it from .remote_sources
  • Manually delete .remote_sources
  • Call search "summary", this time it will list it from the source url https://github.com/lightningd/plugins

8. uninstall "<plugin>" Leaves disable-plugin in Config

The plugin directory is removed, but an entry remains in bitcoin-reckless.conf as disable-plugin=<plugin>, unsure if this is intentional. Though RPC still shows correct enabled/disabled state.

9. Invalid or Missing Subcommands Crash the Process

It should return a structured error instead of crashing.
Example failing commands: search, add, remove, source, source "xyz", update, update "summary"

$ lightning-cli reckless source
{
   "code": -3,
   "message": "the reckless process has crashed"
}

10. reckless help Output Is Not Formatted

11. reckless --version Returns CLN Version

It should return the reckless plugin version instead.

12. Missing Commands in Document Synopsis

The following commands are missing from the documentation synopsis:

search
update
help
listconfig
listavailable
listinstalled

13. Missing Documentation Descriptions

Descriptions are missing for these commands:

listavailable
listinstalled
listconfig

14. Clear Old Reckless Configurations

[UPDATE]: After reconsideration, this feels like a low-priority UI feature. Users should explicitly choose to clear one plugin at a time. A factory-reset-style option may be premature for the UI.


Please note that I haven’t reviewed the code yet. To save time and effort, I’ll begin the code review once these commands have matured and are working as expected.

@ShahanaFarooqui
Copy link
Collaborator

ShahanaFarooqui commented Nov 15, 2025

@endothermicdev I am listing our last discussion point here too for posterity & completeness:

15. Lightning CLI Argument Parsing Conflicts With Reckless From Receiving Common Flags

lightning-cli intercepts certain arguments before they can be passed to the reckless plugin, preventing users from accessing reckless-specific information.
Affected arguments:

--help
--version
--conf

@ShahanaFarooqui
Copy link
Collaborator

  1. Clear Old Reckless Configurations
    [UPDATE]: After reconsideration, this seems like a low-priority UI feature. Users should explicitly choose to remove plugins individually. A full factory-reset approach may be premature for the UI.

@endothermicdev
Apologies for the earlier confusion and for not documenting this requirement more clearly. What I actually intended was a way to uninstall a plugin when the Core Lightning node cannot start because that plugin is causing a failure.

This does not need to be available through RPC, since the goal is to provide a recovery mechanism only when the CLN node is unable to start normally. This is mainly a safety and recovery feature rather than a user-facing management option.

For example, if I install the summary plugin, then prometheus, and later the backup plugin, and the backup plugin prevents the lightning node from starting, I would like the reckless plugin to be able to:

  • uninstall the backup plugin,
  • remove its configuration entries, and
  • restart the Core Lightning node successfully.

@endothermicdev endothermicdev force-pushed the reckless-ui-features branch 2 times, most recently from ac83556 to 3d2cd8d Compare December 17, 2025 20:37
@endothermicdev endothermicdev force-pushed the reckless-ui-features branch 2 times, most recently from 13766cc to e0bb38a Compare January 8, 2026 22:15
@endothermicdev endothermicdev force-pushed the reckless-ui-features branch 3 times, most recently from a37dd85 to f5e078e Compare February 2, 2026 17:56
This doesn't change the argparse behavior with --help/-h, but it does
correct the output in this one case where we must manually call it.
This is needed when installation is managed by an application
that may not have access to the filesystem to clean up manually.
'Reckless listinstalled' will now list all plugins installed and managed
by reckless.
Changelog-Added: reckless: `listinstalled` command lists plugins installed by reckless.
Keep state on the clone and subdirectories so that
subsequent access doesn't try fetching again.
Allows listconfig, listinstalled, and listavailable to be called
via rpc.  Also allow processing non-array result in listconfig output.
…stall

reckless listavailable sorts through the available sources to
find plugins for which we have installers.

Changelog-Added: reckless gained the 'listavailable' command to list available plugins from reckless' sources.
Requested by @ShahanaFarooqui while accessing reckless via rpc
in order to find out where the plugins are installed and
enabled.
The manifest.json provides a short and long description
of the plugin, dependencies, and specifies the entrypoint
in case it's not named the same as the plugin.

changelog-changed: Reckless uses a manifest in the plugin directory to gain additional details about plugin and installation.
This allows plugins with a uv run script to install
themselves.  Unfortunately it requires file access to all
potential entrypoints to check if they are installable.

Changelog-Added: reckless can now install plugins executable by shebang.
The shebang installer requires introspection of files, and
the listavailable command reads the manifest for each
plugin.  Due to the need for file access, cloning all remote
repositories is now simpler and faster, so it's time to rip
out the github API access code.
Including the canned server in the pytest infrastructure.
with higher level repository contents.
Changelog-Fixed: Fixes an issue where reckless would misread the contents of an uncloned repository submodule.
This will be useful for lightning-rpc so that logs can be
read while waiting on reckless to return json output once
complete.
Changelog-added: The reckless-rpc plugin streams logs via the notification topic 'reckless_log'
Otherwise reckless-rpc can be concerned that the reckless
utility process didn't exit cleanly.
This is the standard battle-tested way of doing it, and it avoids the
various bugs in the open-coded implementation.

Inspired by common/jsonrpc_io.c which does a similar thing for JSON.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
@ShahanaFarooqui
Copy link
Collaborator

Hi @endothermicdev,

Thanks for the updates. I tested reckless with your last commit dd9cae869142ef65c66cd3dc79bdf37882e87ada and have shared my observations below. Please let me know if you need any clarification or additional details.

Documentation:

  • Can we add documentation for reckless event_notifications?
  • It would also help to explicitly document that reckless install streaming only works when not using --json flag.

Streaming & notifications

  • lightning-cli reckless install is not streaming logs.
  • clnrest does capture reckless_log via event_notifications, but all Reckless commands (source list, install, uninstall, etc.) emit the same event notification. From a UI perspective, this makes it difficult to uniquely associate responses with requests. Recording this for posterity: we agreed to include a unique RPC request ID in notifications so they can be reliably identified.
  • Since we are already updating these notifications, it would be great to introduce command-specific notification topics, such as reckless-source-list, reckless_install, and reckless_uninstall, instead of using the generic reckless_log.

Install stability

  • lightning-cli reckless install OR curl -k -X 'POST' 'https://localhost:3011/v1/reckless' -H 'rune: $RUNE' -d '{"command": "install", "target/subcommand": "plugin-name"}' in most cases kills lightningd on the first or second install (install → uninstall → install).
  • Tested installs for: sling, clnrod, datastore, backup, bolt12-prism, persistent-channels, c-lightning-graphql, prometheus, summary.

Commit-specific installs

Currently, my all attempts to install a plugin with a commit sha failed. Like lightning-cli reckless install "8c675f9" sling or lightning-cli reckless install "@8c675f9" sling.

UX / consistency issues

  • lightning-cli listconfigs vs lightning-cli reckless listconfig: RPC naming is confusing.
  • Help commands:
    • lightning-cli reckless help source
    • lightning-cli reckless source help
    • lightning-cli reckless source list "sling"
    • Above commands throw error message “the reckless process has crashed” is scary but at least it doesn't crash lightningd.

Version mismatch:

lightning-cli reckless --version returns v25.12-265-gdd9cae8, while reckless --json --version returns {"result": "v25.12"], "log": ["INFO: v25.12"]}

listavailable output issues

  • lightning-cli reckless listavailable: Response is not formatted correctly (JSON strings inside result[]).
  • Also wanted to confirm whether short_description, long_description, and requirements are genuinely null / [] for all plugins, or if they are dropped during list construction.

Initial run kills/hangs with listavailable

  • On a new node, running the clnrest command curl -k -X 'POST' 'https://localhost:3011/v1/reckless' -H 'rune: $RUNE' -d '{"command": "listavailable"}' creates the reckless config but causes lightningd to terminate while sending the response.
  • The command reckless --json listavailable hangs after prompting to create a new config. After KeyboardInterrupt, the config is created and subsequent runs work fine (stack trace below for reference):
config file not found: /home/shahana/workspace/dummy-networks/regtest-network-27.01.26/cln1/regtest/config
press [Y] to create one now.
y
config file not found: /home/shahana/workspace/dummy-networks/regtest-network-27.01.26/cln1/reckless/regtest-reckless.conf
config file not found: /home/shahana/workspace/dummy-networks/regtest-network-27.01.26/cln1/reckless/.sources


^CTraceback (most recent call last):
 File "/usr/local/bin/reckless", line 2532, in <module>
RECKLESS_SOURCES = load_sources()
  ^^^^^^^^^^^^^^
 File "/usr/local/bin/reckless", line 2000, in load_sources
all_sources.append(LoadedSource(src))
  ^^^^^^^^^^^^^^^^^
 File "/usr/local/bin/reckless", line 353, in __init__
self.local_clone = copy_remote_git_source(InstInfo(None, source))
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/usr/local/bin/reckless", line 680, in copy_remote_git_source
_git_clone(github_source, local_path, verbose)
 File "/usr/local/bin/reckless", line 1279, in _git_clone
git = run(['git', 'clone', '--recurse-submodules', source, str(dest)],
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/usr/lib/python3.12/subprocess.py", line 550, in run
stdout, stderr = process.communicate(input, timeout=timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/usr/lib/python3.12/subprocess.py", line 1209, in communicate
stdout, stderr = self._communicate(input, endtime, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/usr/lib/python3.12/subprocess.py", line 2115, in _communicate
ready = selector.select(timeout)
^^^^^^^^^^^^^^^^^^^^^^^^
 File "/usr/lib/python3.12/selectors.py", line 415, in select
fd_event_list = self._selector.poll(timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants