- Replace all shell=True subprocess calls with Python-native processing
(nodeconnection.py, SPV/nodeconnection.py, SPV/ppi.py)
- Mask sensitive inputs (private keys, passwords, tokens) with getpass
- Add threading.Lock to block_explorer.py shared state
- Use json.loads() instead of fragile string splitting in apisnd.py
- Add path validation before file open in apisnd.py
- Replace random.randint with secrets.randbelow for mining nonces
- Fix destructive exception handlers in clone.py and feed.py
- Replace bare except clauses with specific exceptions + logging
- Remove unused imports (psutil, xmltodict, block_visualizer, base64, say)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace all dynamic .split() patterns in subprocess calls with safe
alternatives: shlex.split(), explicit list args, and _run_btc/_run_ln
helpers in PyBlock.py. Covers PyBlock, block_visualizer, clockscript,
lastblockdetail, mempoolclock, nodeconnection, and ai/context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Centralize bitcoin-cli subprocess calls into a single _run_cli()
function with nosemgrep annotation. The cli path is already
sanitized via shlex.split() before reaching this function.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add cyan separator lines (────) before and after AI responses
- Change prompt to 'pyblock>' in yellow to distinguish from AI text
- Balance shown below the closing separator in dim
- Add UTF-8 env vars to entrypoint.sh for ttyd/Docker contexts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rich Console renders to a StringIO buffer, then the result is
encoded as UTF-8 bytes and written directly to sys.stdout.buffer,
bypassing Python's stdout encoding which may not be UTF-8 in all
launch contexts (ttyd, Docker, pipes).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reconfigure sys.stdout to UTF-8 when the ai module loads, ensuring
accented characters (á, é, ñ, ¡, ¿) render correctly regardless
of how PyBLOCK was launched.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Force Rich Console to use UTF-8 output encoding so Spanish
accented characters render correctly in the terminal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use shlex.split() to safely parse bitcoincli path before passing
to subprocess.run(), same pattern as clock/data.py fix.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The status line after 'U' (usage) showed the old balance instead
of refreshing it from the API. Now calls get_balance() before
displaying the status line.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major UX improvements inspired by KCode's terminal rendering:
- Continuous chat flow — no screen clearing between messages,
conversation scrolls naturally like a real chat
- Rich Markdown rendering for AI responses — proper tables,
code blocks with syntax highlighting, headers, bold, bullets
- Remove "Press Enter to continue" interruption from chat loop
- Compact status line showing balance + commands inline
- Ctrl+C returns to main menu cleanly
- Balance updates shown inline after each response
- Context refreshed on each query for up-to-date node data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Client tries the public URL first (api.astrolexis.space), and
falls back to localhost:10400 on 404 or connection errors. This
handles CDN cache issues and provides resilience when the gateway
runs on the same machine as PyBLOCK.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A function with yield is always a generator in Python, so
chat() with stream=False was returning a generator instead
of a dict. Split into chat() for non-streaming (returns dict)
and _stream_chat() for streaming (yields SSE chunks).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New pybitblock/ai/ package integrating with Astrolexis AI Gateway
at https://api.astrolexis.space:
- client.py: API client for auth, top-up (Lightning), chat (SSE
streaming), and usage tracking
- context.py: Gathers Bitcoin/Lightning node data (via CLI, RPC,
or mempool.space API) for AI context injection
- ui.py: Terminal chat interface with conversation history,
Lightning top-up flow with QR codes, usage stats display,
and first-time token setup
Accessible from Main Menu as "I - AI Assistant". All queries go
through Astrolexis gateway — user pays in sats via Lightning.
Token stored in pyblocksettings.conf.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>