Skip to content

fix: prevent onboarding modal freeze on Textual 8.x#290

Merged
bitflicker64 merged 12 commits into
bitflicker64:mainfrom
deepmhatre13:issue-288-textual8-onboarding-freeze
Jul 19, 2026
Merged

fix: prevent onboarding modal freeze on Textual 8.x#290
bitflicker64 merged 12 commits into
bitflicker64:mainfrom
deepmhatre13:issue-288-textual8-onboarding-freeze

Conversation

@deepmhatre13

Copy link
Copy Markdown
Contributor

Closes #288

Summary

This PR fixes the onboarding modal freeze that occurs on Textual 8.x when clicking Save & Enable.

The root cause was the use of set_timer(0.0, ...) for modal dismissal, which can trigger a ZeroDivisionError in newer Textual versions and prevent the onboarding flow from completing.

Changes

  • Added a reusable dismiss_later() helper for modal screens.
  • Replaced all set_timer(0.0, ...) modal dismissal calls with dismiss_later().
  • Updated the following modal screens:
    • HelpScreen
    • OnboardingScreen
    • ResetConfirmScreen
    • MatrixDefragScreen
    • GhostTyperScreen
  • Used a small non-zero delay (0.001s) to avoid the Textual timer issue.
  • Ensured the scheduled callback returns None, preventing AwaitComplete/ScreenError issues during modal dismissal.

Regression Test

Added an end-to-end regression test for the onboarding flow.

The test:

  • launches the application with onboarding enabled,
  • fills the API key field using a fake non-empty key (gsk_test_key),
  • triggers the actual Save & Enable button logic,
  • verifies the onboarding modal closes successfully,
  • confirms the onboarding result is applied to the application configuration.

The test uses widget.press() because pilot.click("#btn-save") results in an OutOfBounds error in the test environment when the button is outside the visible viewport. widget.press() dispatches the same Button.Pressed event and exercises the production code path:

on_button_pressed()
    ↓
dismiss_later()
    ↓
handle_onboarding_result()

Validation

Passed:

pytest tests/test_tui.py -k onboarding -v

Result:

5 passed

Passed:

pytest tests/test_tui.py -k "onboarding or api_key_validation" -v

Result:

6 passed

Verified that:

  • the onboarding modal no longer freezes,
  • no ZeroDivisionError occurs,
  • no ScreenError is raised,
  • onboarding configuration is saved successfully.

Notes

The remaining failures in the full tests/test_tui.py suite are pre-existing NoMatches failures related to DetailsCanvas rendering (#btn-exec-*, #btn-bulk-*, .feed-container) and are unrelated to this onboarding modal fix.

@git-miku git-miku Bot added the needs-triage Awaiting human triage — run /triage to mark as triaged label Jul 17, 2026
@git-miku git-miku Bot added size/M PR changes ~109 lines area/tui area/tui kind/tests kind/tests labels Jul 17, 2026
@git-miku

git-miku Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Tip

👋 Hey @deepmhatre13 — Miku's on it. Here are the most useful commands for this PR:

💬 Command What it does
:miku /review 🔍 Line-by-line review
:miku /review-sc ✏️ Inline suggested changes
:miku /security 🛡️ Security scan
:miku /perf ⚡ Performance notes
:miku /test 🧪 Test suggestions
:miku /summarize 📝 TL;DR

Note

🎓 This repo is part of ECSOC26. Run :miku /ecsoc to add the ECSOC26 label to this PR.

Note

⭐ Star this repo to unlock all commands. Say :miku /help for the full list.

📖 All commands
🤖 AI-powered — 14 commands
Command Description Works on
:miku /ask <question> Answer a question about the codebase Issues & PRs
:miku /review Full code review (auto-fetches diff) PRs only
:miku /review-sc Post inline suggested-change comments PRs only
:miku /security OWASP security review (injection, auth, crypto…) PRs only
:miku /perf Performance & efficiency analysis PRs only
:miku /docs Generate docstrings for changed code PRs only
:miku /test Suggest unit tests for changed code PRs only
:miku /roast Humorous but constructive code roast 🔥 PRs only
:miku /checklist Smart diff-aware PR checklist PRs only
:miku /summarize TL;DR of this issue or PR Issues & PRs
:miku /explain <target> Explain a file, function, or concept Issues & PRs
:miku /changelog Draft a CHANGELOG entry PRs only
:miku /estimate Story-point effort estimate Issues only
:miku /chat <message> General conversation Issues & PRs
🔧 Issue & PR management — 18 commands
Command Description Works on
:miku /assign [@user] Assign to yourself or another user Issues & PRs
:miku /unassign [@user] Remove yourself or another user Issues & PRs
:miku /label <name> Add a label Issues & PRs
:miku /remove-label <name> Remove a label Issues & PRs
:miku /close [reason] Close this issue or PR Issues & PRs
:miku /reopen Reopen a closed issue or PR Issues & PRs
:miku /approve [message] Submit an approving review on a PR PRs only
:miku /retitle <new title> Change the title Issues & PRs
:miku /duplicate #N Mark as duplicate of #N and close Issues & PRs
:miku /milestone [name] Set or list open milestones Issues & PRs
:miku /ship [version] Mark PR as shipped / deployed PRs only
:miku /lock [reason] Lock conversation (resolved / off-topic / spam) Issues & PRs
:miku /unlock Unlock conversation Issues & PRs
:miku /cc @user1 [@user2] Request reviews PRs only
:miku /lgtm [cancel] Signal "Looks Good To Me" Issues & PRs
:miku /hold [cancel] Block merge; :miku /hold cancel releases it Issues & PRs
:miku /wip Toggle WIP (converts PR to draft) Issues & PRs
:miku /merge Merge this PR (CI + approval required) PRs only
🎉 Community & utility — 9 commands
Command Description Works on
:miku /vote Open a 👍 👎 🚀 reaction poll Issues & PRs
:miku /kudos @user [msg] Give public kudos to a contributor Issues & PRs
:miku /stats Repo stars, forks, top contributors Issues & PRs
:miku /remind <dur> <msg> Schedule a reminder (e.g. 2h, 30m, 1d) Issues & PRs
:miku /size Show PR size breakdown PRs only
:miku /ping [@user ...] Ping contributors with an AI message Issues & PRs
:miku /joke Tell a programming joke Issues & PRs
:miku /shrug Add ¯_(ツ)_/¯ label Issues & PRs
:miku /help Show this message Issues & PRs

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces _DeferredDismissMixin to fix a Textual 8.x modal freeze by replacing zero-delay set_timer(0.0, ...) calls with a dismiss_later() helper that uses a 0.001 s delay, and upgrades the onboarding regression test to exercise the full button-press-to-dismiss path with a mocked save_config.

  • tui.py: Mixin is cleanly applied to all five affected modal screens; the change is targeted and the test upgrade properly guards the config-write side effect.
  • insights.py (critical): An unrelated change to detect_late_night_chaotic_sessions inserted new sections 4 and 5 without removing the originals. The first pass deletes project_id from every session dict; the duplicate second pass immediately crashes with KeyError: 'project_id' on any real workload.
  • tests/test_insights.py: The only test covering commit deduplication was deleted without a replacement, removing the safety net for the broken logic above.

Confidence Score: 2/5

Not safe to merge: an unrelated change to detect_late_night_chaotic_sessions in insights.py left a duplicate code block that crashes with KeyError on every real invocation of that function.

The tui.py modal fix is sound, but insights.py contains duplicated sections 4 and 5 where the new block was inserted before the old one without removing it. The first pass deletes project_id from every session dict; the second pass crashes immediately on session["project_id"]. Any user whose history produces at least one late-night chaotic session will hit an unhandled exception. The deleted deduplication test removes the only guard for this logic.

termstory/insights.py lines 496–545 (the duplicate block must be removed) and tests/test_insights.py (the deduplication test needs to be restored or replaced).

Important Files Changed

Filename Overview
termstory/insights.py Duplicate sections 4 and 5 of the commit-fetch logic were inserted without removing the originals; the first pass deletes project_id from every session dict, causing the second pass to crash with KeyError on every real invocation.
termstory/tui.py Introduces _DeferredDismissMixin and applies it to all five modal screens; cleanly replaces set_timer(0.0, ...) calls with dismiss_later(). One set_timer(0.8, self.dismiss) auto-dismiss in MatrixDefragScreen was intentionally left unchanged.
tests/test_tui.py Replaces the structural onboarding test with a proper end-to-end regression test; correctly mocks save_config to prevent writing the developer's real config file.
tests/test_insights.py Deletes test_detect_late_night_chaotic_sessions_no_duplicate_commits without a replacement, removing the only test that guards the commit deduplication logic that is broken in this PR.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant ModalScreen
    participant _DeferredDismissMixin
    participant TextualEventLoop

    User->>ModalScreen: "clicks Save & Enable / presses key"
    ModalScreen->>ModalScreen: "on_button_pressed() / action_*()"
    ModalScreen->>_DeferredDismissMixin: dismiss_later(result)
    _DeferredDismissMixin->>TextualEventLoop: set_timer(0.001, _do_dismiss)
    Note over TextualEventLoop: next event-loop tick (clean state)
    TextualEventLoop->>ModalScreen: "_do_dismiss() -> self.dismiss(result)"
    ModalScreen-->>User: modal closes, result returned to app
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant ModalScreen
    participant _DeferredDismissMixin
    participant TextualEventLoop

    User->>ModalScreen: "clicks Save & Enable / presses key"
    ModalScreen->>ModalScreen: "on_button_pressed() / action_*()"
    ModalScreen->>_DeferredDismissMixin: dismiss_later(result)
    _DeferredDismissMixin->>TextualEventLoop: set_timer(0.001, _do_dismiss)
    Note over TextualEventLoop: next event-loop tick (clean state)
    TextualEventLoop->>ModalScreen: "_do_dismiss() -> self.dismiss(result)"
    ModalScreen-->>User: modal closes, result returned to app
Loading

Reviews (4): Last reviewed commit: "Merge branch 'main' into issue-288-textu..." | Re-trigger Greptile

Comment thread termstory/tui.py
Comment thread termstory/tui.py Outdated
Comment thread tests/test_tui.py
@deepmhatre13

Copy link
Copy Markdown
Contributor Author

:miku

@bitflicker64

Copy link
Copy Markdown
Owner

@deepmhatre13 Can you prove the fix works? Can you record a video and send it here? I'll definitely give you a good backend label so you get the maximum points in ESOC. Also, if you find any other issues, can you just file them too? If you want, you can claim them. I'll definitely give you good labels so you can score better in ECSOC.

@bitflicker64

Copy link
Copy Markdown
Owner

I don’t have much time to search for and file issues here. I have a reliable bot that can file them, but it’s often just the usual situation. I was wondering if you could file some issues and perhaps claim them, or at least allow me to add the ECSOC labels to them. Also, the good labels can earn extra points, definitely.

@bitflicker64

Copy link
Copy Markdown
Owner

Also, could you find out whether the labels are stackable? If they are, I can give you multiple labels to earn a lot of points. I would appreciate it if you could look into this. Thank you.

@deepmhatre13

Copy link
Copy Markdown
Contributor Author

Hi @bitflicker64,

I've verified the fix locally and in CI.

Local verification

  • Ran the onboarding regression suite:

    pytest tests/test_tui.py -k "onboarding or api_key_validation" -v
  • Result: 6 passed, 25 deselected.

This includes the new end-to-end onboarding regression test that exercises the actual Save & Enable flow.

CI verification

  • All GitHub checks passed:

    • Python 3.9 ✅
    • Python 3.10 ✅
    • Python 3.11 ✅
    • Python 3.12 ✅
    • Lint ✅
    • Greptile ✅

I've attached screenshots of the local test results and the successful CI checks as proof.
image
image

@deepmhatre13

Copy link
Copy Markdown
Contributor Author

Hi @bitflicker64! I checked the publicly available ECSoC documentation, but I couldn't find any official mention of whether labels are stackable for scoring. It doesn't seem to be covered in the program rules.

If there's an internal guideline or admin clarification about label stacking, I'd be happy to follow that. Otherwise, I couldn't verify that multiple labels contribute additional points.

@bitflicker64

Copy link
Copy Markdown
Owner

Hi @bitflicker64! I checked the publicly available ECSoC documentation, but I couldn't find any official mention of whether labels are stackable for scoring. It doesn't seem to be covered in the program rules.

If there's an internal guideline or admin clarification about label stacking, I'd be happy to follow that. Otherwise, I couldn't verify that multiple labels contribute additional points.

Screen.Recording.2026-07-17.at.7.58.57.PM.mov

@bitflicker64

Copy link
Copy Markdown
Owner

@deepmhatre13 I'm currently working on containerization in one of Apache projects , so I'm a bit busy, but I'm still finding time to test it. I'll quickly make a video. You can test it in WSL since you have a Windows laptop, not a Mac or Linux. This was originally intended for Mac, but it should work on Linux as well. You can try it with WSL. You can contact me here, or we can connect on Discord. I'll send you a link right now; let me know if it works. Please confirm here, and I'll re‑run it. https://discord.gg/PHcXrachS

@bitflicker64

Copy link
Copy Markdown
Owner

:miku /label good-backend
:miku /label good-pr

@git-miku git-miku Bot added good-backend good-backend good-pr good-pr labels Jul 17, 2026
@git-miku

git-miku Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

miku /label

🏷️ Added label good-backend.


miku /label

🏷️ Added label good-pr.

@bitflicker64

Copy link
Copy Markdown
Owner

Until then, you can take on small PRs so you continue earning points, too. Thanks.

Copy link
Copy Markdown
Owner

Thanks for fixing the Textual timer crash. I think there is one more practical issue left: the onboarding modal is still tall enough that Save & Enable can sit below the visible area in normal terminals such as 120x40, so the flow can still look stuck even though the timer crash is fixed.

The fix I would apply is to shorten the onboarding copy and reduce the modal vertical spacing:

diff --git a/termstory/tui.py b/termstory/tui.py
@@
             Static("🔒 TermStory Privacy & AI Onboarding", id="modal-title"),
             Static(
-                "TermStory is completely offline by default. No data ever leaves your machine.\n\n"
-                "To make your timeline readable, you can optionally enable the AI Categorization Engine. "
-                "This will send sanitized terminal commands to an LLM to generate short, human-readable session memories.\n\n"
+                "TermStory is offline by default. If you enable AI, only sanitized terminal commands are sent "
+                "to your selected provider to create short session memories.\n\n"
                 "Before sending, TermStory scrubs passwords, environment variables, IPs/FQDNs, and drops "
-                "sensitive sessions containing commands like 'vault' or 'aws configure' entirely.\n\n"
-                "[dim]Shortcuts: [bold]Ctrl+g[/]: Groq, [bold]Ctrl+a[/]: OpenAI, [bold]Ctrl+l[/]: Ollama, [bold]Ctrl+c[/]: Custom, [bold]Ctrl+d[/]: Disable AI, [bold]Esc[/]: Cancel[/dim]",
+                "sensitive sessions such as vault or aws configure.\n\n"
+                "[dim]Shortcuts: Ctrl+g Groq, Ctrl+a OpenAI, Ctrl+l Ollama, Ctrl+c Custom, Ctrl+d Disable, Esc Cancel[/dim]",
                 id="modal-desc"
             ),
@@
         width: 90%;
         max-width: 75;
         height: auto;
-        padding: 2;
+        padding: 1;
         content-align: center middle;
@@
     .input-label {
         color: #88889a;
-        margin-top: 1;
+        margin-top: 0;
         margin-left: 1;
         text-style: bold;
     }

I checked this locally on the PR branch:

pytest tests/test_tui.py -k "api_key_validation" -q
# 1 passed, 30 deselected

I also probed the Textual layout at 120x40; after this patch, #btn-save renders at y=35, height 3, so it stays within the 40-row screen and remains visible/clickable. This complements the timer fix rather than replacing it.

@bitflicker64 bitflicker64 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Code Review Summary

Verdict: Approve with minor suggestions — real fix for Textual 8.x modal freeze; good E2E regression test. A few cleanups would make this more maintainable.

Intent

Stop onboarding / modal dismiss from freezing under Textual 8.x by scheduling dismiss off the button message pump with a non-zero timer delay (issue #288).

Impact

  • Replaces set_timer(0.0, ...) with dismiss_later using 0.001s delay and optional result.
  • Applied across Help, Onboarding, ResetConfirm, MatrixDefrag, GhostTyper screens.
  • Test rewritten to press real Save & Enable path and wait for screen pop — much better than the previous structural mock.

What’s correct

  • Root cause analysis (AwaitComplete / ScreenError on zero-delay dismiss inside message handler) matches known Textual 8 behavior.
  • CI green.
  • Non-empty API key path exercised without network.

Suggestions

  1. DRY dismiss_later — identical 3-line method is copy-pasted on 5 classes. Prefer a small mixin / helper base, e.g. class DeferredDismissMixin: ..., to avoid future drift.
  2. Lambda style(self.dismiss(result), None)[1] works but is opaque; lambda r=result: self.dismiss(r) (or a tiny local def) is clearer and avoids the tuple trick.
  3. Config isolation in the new test — confirm save_config cannot write the developer’s real config file when Save is pressed (monkeypatch termstory.tui.save_config / config path if not already covered by workspace config override).
  4. Comment why 0.001 not 0.0 — one line in dismiss_later docstring helps the next person not “optimize” it back to zero.

Verdict

Comment / soft approve — mergeable after optional DRY + config-safety check; not blocking if you confirm the test doesn’t touch real HOME config.

Comment thread termstory/tui.py Outdated

def dismiss_later(self, result=None) -> None:
"""Dismiss this modal screen on the next tick with a non-zero delay."""
self.set_timer(0.001, lambda: (self.dismiss(result), None)[1])

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Works, but the tuple trick is hard to read and this method is duplicated on several screens. Consider:

def dismiss_later(self, result=None) -> None:
    """Dismiss on the next timer tick (non-zero delay required on Textual 8.x)."""
    def _do_dismiss() -> None:
        self.dismiss(result)
    self.set_timer(0.001, _do_dismiss)

and/or a shared mixin so Help/Onboarding/Reset/Matrix/GhostTyper don’t each redefine it.

Comment thread tests/test_tui.py
await pilot.pause()

# Verify the modal dismissed and the result reached the app.
assert not isinstance(app.screen, OnboardingScreen)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Nice end-to-end path. Please double-check (or monkeypatch) that Save does not persist to the real user config under $HOME during CI/dev runs — e.g. monkeypatch.setattr("termstory.tui.save_config", lambda cfg: None) if the onboarding success path writes config.

@bitflicker64

Copy link
Copy Markdown
Owner

/triage

@git-miku git-miku Bot added triage/triaged This PR has been triaged by a maintainer and removed needs-triage Awaiting human triage — run /triage to mark as triaged labels Jul 18, 2026
@git-miku

git-miku Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

miku /triage

✅ Marked as triaged (triage/triaged applied, needs-triage removed).

@bitflicker64

Copy link
Copy Markdown
Owner

:miku /check-star

@git-miku git-miku Bot added the do-not-merge/needs-star PR author has not starred this repo — run /check-star after starring label Jul 18, 2026
@git-miku

git-miku Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

miku /check-star

@deepmhatre13 still hasn't starred this repo. Applied do-not-merge/needs-star.

Star this repo first, then run :miku /check-star again. ⭐

@deepmhatre13

Copy link
Copy Markdown
Contributor Author

:miku /check-star

@git-miku git-miku Bot added needs-triage Awaiting human triage — run /triage to mark as triaged and removed do-not-merge/needs-star PR author has not starred this repo — run /check-star after starring labels Jul 18, 2026
@git-miku

git-miku Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Tip

👋 Hey @deepmhatre13 — Miku's on it. Here are the most useful commands for this PR:

💬 Command What it does
:miku /review 🔍 Line-by-line review
:miku /review-sc ✏️ Inline suggested changes
:miku /security 🛡️ Security scan
:miku /perf ⚡ Performance notes
:miku /test 🧪 Test suggestions
:miku /summarize 📝 TL;DR

Note

🎓 This repo is part of ECSOC26. Run :miku /ecsoc to add the ECSOC26 label to this PR.

Note

⭐ Star this repo to unlock all commands. Say :miku /help for the full list.

📖 All commands
🤖 AI-powered — 14 commands
Command Description Works on
:miku /ask <question> Answer a question about the codebase Issues & PRs
:miku /review Full code review (auto-fetches diff) PRs only
:miku /review-sc Post inline suggested-change comments PRs only
:miku /security OWASP security review (injection, auth, crypto…) PRs only
:miku /perf Performance & efficiency analysis PRs only
:miku /docs Generate docstrings for changed code PRs only
:miku /test Suggest unit tests for changed code PRs only
:miku /roast Humorous but constructive code roast 🔥 PRs only
:miku /checklist Smart diff-aware PR checklist PRs only
:miku /summarize TL;DR of this issue or PR Issues & PRs
:miku /explain <target> Explain a file, function, or concept Issues & PRs
:miku /changelog Draft a CHANGELOG entry PRs only
:miku /estimate Story-point effort estimate Issues only
:miku /chat <message> General conversation Issues & PRs
🔧 Issue & PR management — 18 commands
Command Description Works on
:miku /assign [@user] Assign to yourself or another user Issues & PRs
:miku /unassign [@user] Remove yourself or another user Issues & PRs
:miku /label <name> Add a label Issues & PRs
:miku /remove-label <name> Remove a label Issues & PRs
:miku /close [reason] Close this issue or PR Issues & PRs
:miku /reopen Reopen a closed issue or PR Issues & PRs
:miku /approve [message] Submit an approving review on a PR PRs only
:miku /retitle <new title> Change the title Issues & PRs
:miku /duplicate #N Mark as duplicate of #N and close Issues & PRs
:miku /milestone [name] Set or list open milestones Issues & PRs
:miku /ship [version] Mark PR as shipped / deployed PRs only
:miku /lock [reason] Lock conversation (resolved / off-topic / spam) Issues & PRs
:miku /unlock Unlock conversation Issues & PRs
:miku /cc @user1 [@user2] Request reviews PRs only
:miku /lgtm [cancel] Signal "Looks Good To Me" Issues & PRs
:miku /hold [cancel] Block merge; :miku /hold cancel releases it Issues & PRs
:miku /wip Toggle WIP (converts PR to draft) Issues & PRs
:miku /merge Merge this PR (CI + approval required) PRs only
🎉 Community & utility — 9 commands
Command Description Works on
:miku /vote Open a 👍 👎 🚀 reaction poll Issues & PRs
:miku /kudos @user [msg] Give public kudos to a contributor Issues & PRs
:miku /stats Repo stars, forks, top contributors Issues & PRs
:miku /remind <dur> <msg> Schedule a reminder (e.g. 2h, 30m, 1d) Issues & PRs
:miku /size Show PR size breakdown PRs only
:miku /ping [@user ...] Ping contributors with an AI message Issues & PRs
:miku /joke Tell a programming joke Issues & PRs
:miku /shrug Add ¯_(ツ)_/¯ label Issues & PRs
:miku /help Show this message Issues & PRs

@git-miku

git-miku Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

miku /check-star

@deepmhatre13 has starred the repo — removed do-not-merge/needs-star and applied needs-triage. This PR is now in the triage queue and area labels have been applied. ✨

@git-miku git-miku Bot added size/L PR changes ~361 lines area/ai area/ai area/cli area/cli kind/docs kind/docs and removed size/M PR changes ~109 lines labels Jul 19, 2026
@git-miku git-miku Bot added size/M PR changes ~109 lines and removed size/L PR changes ~361 lines labels Jul 19, 2026
@bitflicker64
bitflicker64 merged commit 9a422ca into bitflicker64:main Jul 19, 2026
2 of 6 checks passed
@bitflicker64

Copy link
Copy Markdown
Owner

/ecsoc

@git-miku git-miku Bot added the ECSoC26 label Jul 19, 2026
@git-miku

git-miku Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

miku /ecsoc

🏷️ Added ECSOC26.

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

Labels

area/ai area/ai area/cli area/cli area/tui area/tui ECSoC26-L2 ECSoC26 good-backend good-backend good-pr good-pr kind/docs kind/docs kind/tests kind/tests needs-triage Awaiting human triage — run /triage to mark as triaged size/M PR changes ~109 lines triage/triaged This PR has been triaged by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Onboarding Save & Enable freezes with current Textual 8.x installs

4 participants