Skip to content

Core: Fix logger.logBox from being cut out by clack.taskLog relative cursor#34729

Open
huang-julien wants to merge 4 commits into
nextfrom
fix/clack_cut_log
Open

Core: Fix logger.logBox from being cut out by clack.taskLog relative cursor#34729
huang-julien wants to merge 4 commits into
nextfrom
fix/clack_cut_log

Conversation

@huang-julien
Copy link
Copy Markdown
Contributor

@huang-julien huang-julien commented May 6, 2026

What I did

This bug has been discovered within #34718

When a prompt.taskLog(...) session is active, any direct stdout write performed during that session would be partially or fully overwritten by clack's next's clacjk.message call.

clack.ztaskLog tracks lines it emits itself. On .message(), it does erase-and-redraw and on .sucess()/.error(), it erase the title region.

Direct calls tro process.stoud.write from outside clack advance the real cursor invisibly, so the erase region drifts past clack's intended target and clobbers external content.

--

Before:

image

after:

image

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

  • Verify that. any log or migration logs doesn't break

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Bug Fixes
    • Improved task logging stability when external stdout activity occurs, preserving correct rendering and cleanup for root and nested logs.
  • Refactor
    • Simplified task group delegation and message handling to make nested group rendering and message forwarding more reliable.

@huang-julien huang-julien added bug ci:daily Run the CI jobs that normally run in the daily job. labels May 6, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ccb687e5-c9c2-4c12-9b5a-7b5d9208626d

📥 Commits

Reviewing files that changed from the base of the PR and between 232dae6 and 0f9796c.

📒 Files selected for processing (1)
  • code/core/src/node-logger/prompts/prompt-provider-clack.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/core/src/node-logger/prompts/prompt-provider-clack.ts

📝 Walkthrough

Walkthrough

Refactors clack-based task/group logging to detect external stdout writes during a root taskLog. Adds module-scope stdout-hook and contamination tracking, routes messages through clack.log when contamination is detected, and changes group handling to delegate to the underlying task.group and wrap messages via wrapTextForClack.

Changes

Contamination-Aware TaskLog Logging

Layer / File(s) Summary
Contamination Detection Infrastructure
code/core/src/node-logger/prompts/prompt-provider-clack.ts (lines ~39–88)
Added module-scope state, flags, and helpers to install/uninstall a stdout-write hook and run code under a tracked context to detect external stdout activity.
Enhanced TaskLog Routing & Lifecycle
code/core/src/node-logger/prompts/prompt-provider-clack.ts (lines ~175–279)
Reworked taskLog to install the stdout hook for root tasks, track contamination, route messages via clack.log when contaminated (avoiding erase/redraw), reuse parent hooks for nested tasks, and uninstall hooks/clear current task state on completion or error.
Group Behavior under Contamination
code/core/src/node-logger/prompts/prompt-provider-clack.ts (lines ~175–279)
When contamination is detected, groups are stubbed to bypass erase-and-redraw behavior and messages are emitted without interactive group redraws.
Group Message Forwarding / Wrapping
code/core/src/node-logger/prompts/prompt-functions.ts (lines ~204–216)
Interactive TaskLog group wrapper now delegates to task.group(title) to obtain an inner group and returns wrappers that forward messages to that inner group after applying wrapTextForClack.

Sequence Diagram

sequenceDiagram
    participant Root as Root TaskLog
    participant Hook as Stdout Hook
    participant Detect as Contamination Detector
    participant Msg as Message Router
    participant Clack as Clack Log
    participant Task as Underlying Task
    participant Ext as External Writer

    Root->>Hook: Install stdout-write hook
    Hook->>Detect: Begin tracking writes
    Note over Root,Task: Normal taskLog operation
    Ext->>Hook: External stdout write
    Hook->>Detect: Mark contamination
    Root->>Msg: Emit message
    Msg->>Detect: Check contamination
    alt Contaminated
        Msg->>Clack: Emit via clack.log (no erase/redraw)
    else Clean
        Msg->>Task: Forward to underlying task/group
    end
    Root->>Hook: Uninstall hook on completion
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@code/core/src/node-logger/prompts/prompt-provider-clack.ts`:
- Around line 192-204: The wrapper unconditionally pops the current task log
even for nested taskLog() calls; ensure we only unwind entries this wrapper
created by tracking ownership when calling setCurrentTaskLog()/taskLog() (e.g.,
a boolean like createdCurrentLog) and only call uninstallStdoutHook(),
clearCurrentTaskLog(), and any pop from STORYBOOK_CURRENT_TASK_LOG when that
ownership flag is true; update the error and success branches (the handlers
around uninstallStdoutHook(), hasExternalStdoutWrite, task.error, task.success,
and clearCurrentTaskLog) to check this ownership flag before mutating global
state so nested calls don’t remove parent entries.
- Around line 243-269: The code currently calls setCurrentTaskLog(group) which
pushes the raw clack group onto the active-task stack and bypasses the
contamination-rerouting logic; change it to push the wrapped group (the same
wrapper used on the root path) instead of the raw group so getCurrentTaskLog()
returns the wrapped object with contamination protection—locate where
runTracked(() => task.group(title)) creates group and replace the
setCurrentTaskLog call to use the existing wrapped wrapper object (the one used
elsewhere for the root path) so subsequent message/success/error consumers go
through the contamination checks.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 30c6a78d-8bbe-4aeb-aa0b-6d68488ac239

📥 Commits

Reviewing files that changed from the base of the PR and between e4ac3cc and 232dae6.

📒 Files selected for processing (2)
  • code/core/src/node-logger/prompts/prompt-functions.ts
  • code/core/src/node-logger/prompts/prompt-provider-clack.ts

Comment thread code/core/src/node-logger/prompts/prompt-provider-clack.ts Outdated
Comment thread code/core/src/node-logger/prompts/prompt-provider-clack.ts
@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented May 6, 2026

Package Benchmarks

Commit: 92c4ab5, ran on 7 May 2026 at 15:19:36 UTC

No significant changes detected, all good. 👏

@github-actions github-actions Bot added the Stale label May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-scan:human bug ci:daily Run the CI jobs that normally run in the daily job. Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant