Skip to content

Add Codex auth TUI, earned resets, and automatic patch maintenance#1

Merged
editnori merged 2 commits into
mainfrom
feature/tui-reset-credits-v0.1.0
Jul 11, 2026
Merged

Add Codex auth TUI, earned resets, and automatic patch maintenance#1
editnori merged 2 commits into
mainfrom
feature/tui-reset-credits-v0.1.0

Conversation

@editnori

@editnori editnori commented Jul 11, 2026

Copy link
Copy Markdown
Owner

What changed

  • Adds the persistent Textual watch, manual switch, and dry-run/live autoswitch surfaces.
  • Saves the current Codex auth as a named profile from the TUI.
  • Shows rateLimitResetCredits.availableCount per profile and adds a Cancel-default earned-reset flow.
  • Uses the documented Codex app-server consume method without switching the active profile.
  • Reuses one idempotency key across ambiguous retries and treats alreadyRedeemed as success.
  • Keeps patched Codex aligned with official curl updates through immutable generations and an idempotent maintenance job.
  • Adds deterministic synthetic PNG/GIF/MP4 captures, credential exclusions, CI, install notes, and rollback notes.

Safety boundaries

  • Reset consumption requires explicit confirmation in both the TUI and CLI.
  • The selected profile is refreshed before confirmation and revalidated against cached credential state under the mutation lock.
  • Reset redemption runs in an isolated temporary Codex home and compare-and-swaps any token rotation back only when account lineage still matches.
  • Reset redemption never changes the active profile.
  • reports/, local auth files, caches, and capture frames are ignored and were not staged.

Verification

  • 63 shell integration tests
  • 70 Python/Textual tests
  • Bash syntax, Python compile, lockfile, and whitespace checks
  • Deterministic media regeneration with byte-for-byte --check
  • PNG/GIF/MP4 dimensions, timing, codec, and no-audio verification
  • Credential and path scan of staged text and generated media
  • Installed-runtime smoke test with media-only dependencies excluded
  • Live read-only account/rateLimits/read confirmed the current saved profile reports 2 earned resets; no reset was consumed

Summary by CodeRabbit

  • New Features

    • Added a Textual dashboard for monitoring profiles, usage, switching, reset credits, and automatic account management.
    • Added dry-run and live watch modes with configurable thresholds, cooldowns, and keyboard controls.
    • Improved Codex installation, update recovery, standalone binary detection, and automatic patch maintenance.
    • Added safer profile synchronization, credential handling, reset retries, and atomic state updates.
  • Documentation

    • Updated installation, commands, workflows, accessibility guidance, and release documentation.
  • Tests

    • Expanded shell, integration, TUI, policy, concurrency, and deterministic media validation coverage.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@editnori, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 39 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82facb6f-b863-40dc-a9b5-041adb17cf91

📥 Commits

Reviewing files that changed from the base of the PR and between bc9d675 and af9e18f.

📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • CHANGELOG.md
  • README.md
  • lib/codex-auth/usage.sh
  • tests/run.sh
  • tui/src/codex_auth_tui/engine.py
  • tui/src/codex_auth_tui/models.py
  • tui/src/codex_auth_tui/tui/widgets.py
  • tui/tests/test_engine.py
📝 Walkthrough

Walkthrough

Adds rolling-auth synchronization, generation-aware Codex patching, safer installation and maintenance, a Textual monitoring and autoswitch TUI, deterministic asset generation, expanded documentation, CI, and comprehensive shell/Python test coverage.

Changes

Codex Rolling Auth

Layer / File(s) Summary
Project foundations and release tooling
.github/workflows/ci.yml, .gitignore, CHANGELOG.md, PRODUCT.md, README.md, tui/pyproject.toml, tui/src/codex_auth_tui/*
Adds CI execution, release and product documentation, ignore rules, TUI packaging metadata, and Python entrypoints.
Codex resolution and installation
bin/codex, bin/codex-auth, bin/codex-auth-tui, install.sh, lib/codex-auth/core.sh, lib/codex-auth/help.sh, lib/codex-auth/maintain.sh, lib/codex-auth/run.sh
Hardens binary discovery and wrapper updates, adds staged TUI installation, maintenance locking and cron setup, expands command dispatch, and coordinates subprocess logging.
Active profile and auth state synchronization
lib/codex-auth/core.sh, lib/codex-auth/profiles.sh, lib/codex-auth/usage.sh
Adds versioned active-profile markers, credential identity checks, guarded switching, live-profile synchronization, refresh generations, idempotent reset handling, and compare-and-swap protections.
Generation-aware Codex patching
lib/codex-auth/patch.sh, lib/codex-auth/rolling-auth-v2.patch
Adds stock-keyed patch generations, failure tracking, bundled source patching, generation publication, cache handling, and rolling-auth hooks in AuthManager.
TUI paths, models, settings, backend, and policy
tui/src/codex_auth_tui/{paths,models,settings,backend,engine,cli}.py
Adds immutable account snapshots, path and settings management, shell-backed operations, autoswitch policy decisions, locking, receipts, and CLI parsing.
TUI application and interaction screens
tui/src/codex_auth_tui/tui/*
Adds dashboard, watch, switch, reset, autoswitch, modal, widget, theme, and rendering implementations.
Deterministic TUI asset pipeline
scripts/capture_tui.py, scripts/generate-assets.mjs
Adds sandboxed deterministic capture, sanitized SVG rendering, media assembly and verification, and updates demo labels.
Shell and TUI validation
tests/run.sh, tui/tests/*
Expands integration coverage for installation, patching, profile rotation, resets, concurrency, TUI workflows, autoswitch policy, and CLI validation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CodexAuthTUI
  participant AutoSwitchEngine
  participant ShellBackend
  participant CodexAuthCLI
  participant AuthState
  User->>CodexAuthTUI: launch watch or auto mode
  CodexAuthTUI->>ShellBackend: request snapshot
  ShellBackend->>AuthState: read profiles and usage state
  ShellBackend-->>CodexAuthTUI: return account snapshot
  CodexAuthTUI->>AutoSwitchEngine: start policy loop
  AutoSwitchEngine->>ShellBackend: refresh usage
  ShellBackend->>CodexAuthCLI: run refresh
  CodexAuthCLI->>AuthState: update profile state
  AutoSwitchEngine->>ShellBackend: switch selected profile
  ShellBackend->>CodexAuthCLI: run guarded switch
  CodexAuthCLI->>AuthState: update active auth
  AuthState-->>CodexAuthTUI: refreshed active profile state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main additions: the Codex auth TUI, earned reset support, and automatic patch maintenance.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/tui-reset-credits-v0.1.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc9d675226

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/codex-auth/usage.sh
Comment on lines +667 to +669
if (( count == 0 )); then
print_error "no earned resets available for profile: $name"
return 3

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear stale reset keys when cached credits reach zero

When a prior reset attempt times out before a terminal outcome, reset-$name.pending is intentionally left behind. If a later usage refresh shows availableCount as 0, this early return reports no credits but leaves that pending key on disk; when the account later earns another reset, the code below will reuse the old key and an alreadyRedeemed response can be treated as a successful reset without spending the new credit. Clear the pending key, or bind it to the current fingerprint/credit epoch, before returning on zero credits.

Useful? React with 👍 / 👎.

Comment thread lib/codex-auth/patch.sh
Comment on lines 690 to 692
if [[ ! -f "$source_dir/codex-rs/login/src/auth/manager.rs" ]] \
|| ! grep -Fq 'CODEX_AUTH_ROLLING_ENV_VAR' "$source_dir/codex-rs/login/src/auth/manager.rs"; then
if [[ "$no_fetch" != "1" ]]; then
git -C "$source_dir" fetch origin
fi
|| ! grep -Fq 'maybe_sync_rolling_auth' "$source_dir/codex-rs/login/src/auth/manager.rs"; then
git -C "$source_dir" checkout --detach "$ref"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Always check out the requested patch source ref

When the source directory already contains a previously applied rolling-auth patch, this guard skips git checkout --detach "$ref". Since the default source dir is keyed only by the stock binary, codex-auth patch-codex --force --ref <other-ref> or CODEX_AUTH_PATCH_REF after an earlier build will silently build whatever HEAD was last used while later recording the requested ref in the marker. Check out or verify the requested ref even when the patch is already present.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/codex-auth/help.sh (1)

76-91: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

maintain has no action_rows/tone mapping, so its help label falls back to "Repair" instead of a short verb tag.

usage_all() adds print_help_item "maintain" "Repair shim + queue patch" "$width" (Line 81), but the action_rows table in print_help_item() (Lines 108-136) has no "maintain" pattern. When no pattern matches, the loop's fallback sets action="${desc%% *}", so the rendered action tag becomes "Repair" — inconsistent with the terse verb labels used everywhere else (reset, best, patch, resume, audit, etc.) and with the tone case statement, which also has no branch for it and thus defaults to muted.

🐛 Proposed fix
     "export*"$'\t'"write"
     "help --all"$'\t'"more"
+    "maintain"$'\t'"tend"
   )
-    auth|login|import|wide|refresh|resume|roll|audit|dry|reset)
+    auth|login|import|wide|refresh|resume|roll|audit|dry|reset|tend)
       action_tone="warn"
       ;;

Also applies to: 101-137

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/codex-auth/help.sh` around lines 76 - 91, Add a "maintain" entry to the
action_rows mapping in print_help_item(), assigning a concise action tag such as
"maintain", and add a corresponding tone case so it uses the intended non-muted
styling. Keep usage_all()'s existing help text unchanged and align the new
mapping with the established terse labels used by the other commands.
🧹 Nitpick comments (3)
lib/codex-auth/profiles.sh (1)

149-151: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Read-only commands can block up to 30s (and print a mutation error) on lock contention.

sync_active_profile_from_live runs in a subshell that calls acquire_mutation_lock. When invoked from the mutating paths (cmd_use, cmd_save, cmd_login, cmd_use_if_current) the lock is already held, so re-entry is a no-op. But cmd_list (here) and cmd_current (Line 364) call it without holding the lock, so the subshell tries flock -w "${CODEX_AUTH_MUTATION_LOCK_WAIT:-30}". Under contention a plain list/current will stall for up to 30s and, on timeout, die inside the subshell prints auth change already running before the (still contained) subshell exits and listing continues.

Consider running the sync with a non-blocking/try wait for these read paths so status commands never hang or surface a mutation error.

♻️ One option: short-circuit the wait for read-only callers
 cmd_list() {
   ensure_dirs
-  sync_active_profile_from_live
+  CODEX_AUTH_MUTATION_LOCK_WAIT=0 sync_active_profile_from_live 2>/dev/null || true

(and similarly for cmd_current)

Please confirm the intended contention behavior for read-only commands.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/codex-auth/profiles.sh` around lines 149 - 151, Read-only commands
cmd_list and cmd_current can block on the mutation lock and emit an error.
Update sync_active_profile_from_live or its read-only call sites to use a
non-blocking/try lock acquisition for these commands, while preserving the
existing re-entry behavior for mutating commands such as cmd_use, cmd_save,
cmd_login, and cmd_use_if_current; on contention, status commands should
continue without waiting or printing mutation errors.
install.sh (1)

222-223: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Reconsider the every-minute maintenance cadence.

* * * * * spawns codex-auth maintain 1440×/day. cmd_maintain short-circuits quickly (lock/standalone checks), but a per-minute process launch is unusually aggressive for drift recovery; an hourly or few-minute schedule would cut process churn with negligible impact on recovery latency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install.sh` around lines 222 - 223, Update the cron schedule in the install
script’s cron_command definition to run maintenance less frequently than every
minute, preferably hourly or at a reasonable multi-minute interval, while
preserving the existing PATH and codex-auth maintain --quiet invocation.
tui/src/codex_auth_tui/tui/dashboard.py (1)

140-143: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: make the paired iteration explicit with strict=True.

This branch only runs when names == self._names, so item/account counts already match; adding strict=True documents that invariant and would surface a future divergence loudly instead of silently truncating.

♻️ Optional
-            for item, acc in zip(listview.query(AccountItem), snap.accounts):
+            for item, acc in zip(listview.query(AccountItem), snap.accounts, strict=True):
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tui/src/codex_auth_tui/tui/dashboard.py` around lines 140 - 143, Update the
paired iteration in the dashboard refresh branch to use strict zip semantics,
changing the zip call within the method containing _flash_updated(snap,
listview) to pass strict=True and explicitly enforce matching AccountItem and
account counts.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 15: Update the actions/checkout@v4 step to set persist-credentials:
false, preventing the GitHub token from being stored in the repository’s Git
configuration.

In `@install.sh`:
- Around line 43-47: In the TUI file-copy loop, update the
`${tui_file#$tui_source/}` parameter expansion to quote the `$tui_source/`
prefix, preventing glob metacharacters in the source path from affecting
relative-path calculation.

---

Outside diff comments:
In `@lib/codex-auth/help.sh`:
- Around line 76-91: Add a "maintain" entry to the action_rows mapping in
print_help_item(), assigning a concise action tag such as "maintain", and add a
corresponding tone case so it uses the intended non-muted styling. Keep
usage_all()'s existing help text unchanged and align the new mapping with the
established terse labels used by the other commands.

---

Nitpick comments:
In `@install.sh`:
- Around line 222-223: Update the cron schedule in the install script’s
cron_command definition to run maintenance less frequently than every minute,
preferably hourly or at a reasonable multi-minute interval, while preserving the
existing PATH and codex-auth maintain --quiet invocation.

In `@lib/codex-auth/profiles.sh`:
- Around line 149-151: Read-only commands cmd_list and cmd_current can block on
the mutation lock and emit an error. Update sync_active_profile_from_live or its
read-only call sites to use a non-blocking/try lock acquisition for these
commands, while preserving the existing re-entry behavior for mutating commands
such as cmd_use, cmd_save, cmd_login, and cmd_use_if_current; on contention,
status commands should continue without waiting or printing mutation errors.

In `@tui/src/codex_auth_tui/tui/dashboard.py`:
- Around line 140-143: Update the paired iteration in the dashboard refresh
branch to use strict zip semantics, changing the zip call within the method
containing _flash_updated(snap, listview) to pass strict=True and explicitly
enforce matching AccountItem and account counts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c4c61e0a-cd3b-4417-b5a4-fb638114dbb3

📥 Commits

Reviewing files that changed from the base of the PR and between df9fae6 and bc9d675.

⛔ Files ignored due to path filters (9)
  • assets/codex-auth-auto.png is excluded by !**/*.png
  • assets/codex-auth-demo.gif is excluded by !**/*.gif
  • assets/codex-auth-demo.mp4 is excluded by !**/*.mp4
  • assets/codex-auth-reset.png is excluded by !**/*.png
  • assets/codex-auth-watch.png is excluded by !**/*.png
  • assets/usage-selector.gif is excluded by !**/*.gif
  • assets/usage-selector.png is excluded by !**/*.png
  • assets/usage-selector.svg is excluded by !**/*.svg
  • tui/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (45)
  • .github/workflows/ci.yml
  • .gitignore
  • CHANGELOG.md
  • PRODUCT.md
  • README.md
  • bin/codex
  • bin/codex-auth
  • bin/codex-auth-tui
  • install.sh
  • lib/codex-auth/core.sh
  • lib/codex-auth/help.sh
  • lib/codex-auth/maintain.sh
  • lib/codex-auth/patch.sh
  • lib/codex-auth/profiles.sh
  • lib/codex-auth/rolling-auth-v2.patch
  • lib/codex-auth/run.sh
  • lib/codex-auth/selector.sh
  • lib/codex-auth/usage.sh
  • scripts/capture_tui.py
  • scripts/generate-assets.mjs
  • tests/run.sh
  • tui/README.md
  • tui/pyproject.toml
  • tui/src/codex_auth_tui/__init__.py
  • tui/src/codex_auth_tui/__main__.py
  • tui/src/codex_auth_tui/backend.py
  • tui/src/codex_auth_tui/cli.py
  • tui/src/codex_auth_tui/engine.py
  • tui/src/codex_auth_tui/models.py
  • tui/src/codex_auth_tui/paths.py
  • tui/src/codex_auth_tui/settings.py
  • tui/src/codex_auth_tui/tui/__init__.py
  • tui/src/codex_auth_tui/tui/app.py
  • tui/src/codex_auth_tui/tui/autoview.py
  • tui/src/codex_auth_tui/tui/codex_auth_tui.tcss
  • tui/src/codex_auth_tui/tui/dashboard.py
  • tui/src/codex_auth_tui/tui/data.py
  • tui/src/codex_auth_tui/tui/modals.py
  • tui/src/codex_auth_tui/tui/theme.py
  • tui/src/codex_auth_tui/tui/widgets.py
  • tui/tests/conftest.py
  • tui/tests/test_backend.py
  • tui/tests/test_engine.py
  • tui/tests/test_policy.py
  • tui/tests/test_tui.py

Comment thread .github/workflows/ci.yml
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Set persist-credentials: false on the checkout step.

actions/checkout@v4 persists the GitHub token in .git/config by default. Subsequent shell-script steps in this workflow could inadvertently read it. Add persist-credentials: false to prevent credential leakage.

🛡️ Proposed fix
       - uses: actions/checkout@v4
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- uses: actions/checkout@v4
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 15-15: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 15, Update the actions/checkout@v4 step to
set persist-credentials: false, preventing the GitHub token from being stored in
the repository’s Git configuration.

Source: Linters/SAST tools

Comment thread install.sh
Comment on lines +43 to +47
while IFS= read -r -d '' tui_file; do
tui_relative="${tui_file#$tui_source/}"
mkdir -p "$tui_stage/${tui_relative%/*}"
install -m 0644 "$tui_file" "$tui_stage/$tui_relative"
done < <(find "$tui_source/src" -type f \( -name '*.py' -o -name '*.tcss' \) -print0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Quote the prefix inside the parameter expansion.

${tui_file#$tui_source/} treats $tui_source as a glob pattern; if the source path contains pattern metacharacters the strip can misbehave, yielding wrong relative paths under $tui_stage. Quote it.

🐛 Proposed fix
-  tui_relative="${tui_file#$tui_source/}"
+  tui_relative="${tui_file#"$tui_source"/}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
while IFS= read -r -d '' tui_file; do
tui_relative="${tui_file#$tui_source/}"
mkdir -p "$tui_stage/${tui_relative%/*}"
install -m 0644 "$tui_file" "$tui_stage/$tui_relative"
done < <(find "$tui_source/src" -type f \( -name '*.py' -o -name '*.tcss' \) -print0)
while IFS= read -r -d '' tui_file; do
tui_relative="${tui_file#"$tui_source"/}"
mkdir -p "$tui_stage/${tui_relative%/*}"
install -m 0644 "$tui_file" "$tui_stage/$tui_relative"
done < <(find "$tui_source/src" -type f \( -name '*.py' -o -name '*.tcss' \) -print0)
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 44-44: Expansions inside ${..} need to be quoted separately, otherwise they match as patterns.

(SC2295)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@install.sh` around lines 43 - 47, In the TUI file-copy loop, update the
`${tui_file#$tui_source/}` parameter expansion to quote the `$tui_source/`
prefix, preventing glob metacharacters in the source path from affecting
relative-path calculation.

Source: Linters/SAST tools

@editnori
editnori merged commit 4bcb876 into main Jul 11, 2026
2 checks passed
@editnori
editnori deleted the feature/tui-reset-credits-v0.1.0 branch July 11, 2026 04:33
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.

1 participant