Skip to content

fix: keep subagent spinners animating with session-scoped dirs#244

Open
NOirBRight wants to merge 3 commits into
nicobailon:mainfrom
NOirBRight:fix/session-scoped-spinner-animation
Open

fix: keep subagent spinners animating with session-scoped dirs#244
NOirBRight wants to merge 3 commits into
nicobailon:mainfrom
NOirBRight:fix/session-scoped-spinner-animation

Conversation

@NOirBRight
Copy link
Copy Markdown

Summary

  • combines the session-scoped temp directory fixes currently used by the fork with the spinner animation fix from fix: animate spinner in foreground and async subagent widgets #237
  • keeps running glyphs animated by mixing a time seed into the spinner frame selection
  • renders async widgets dynamically per TUI frame and drives rerenders while jobs are running
  • adds/updates regression coverage for unchanged progress seeds and running widget animation ticks

Verification

  • node --experimental-transform-types --import ./test/support/register-loader.mjs --test test/integration/render-widget.test.ts
  • node --experimental-strip-types --test test/unit/session-scoped-dirs.test.ts
  • node --experimental-strip-types --test test/unit/ensure-accessible-dir.test.ts

Notes

This is intended as the combined upstreamable version of the spinner fix after the fork temporarily pinned session-scoped temp directory work. It supersedes the isolated spinner branch in #237 for users that need both fixes.

Paul Qu added 3 commits May 30, 2026 01:59
…IRS mutable container

- ensureAccessibleDir now catches EPERM/EACCES from mkdirSync, attempts
  rmSync+retry, and falls back to ${dirPath}-${process.pid} when both fail
- Return type changed from void to string (actual path used)
- DIRS mutable container replaces export const RESULTS_DIR/ASYNC_DIR for
  runtime path override propagation
- All 11 consumer module sites migrated to use DIRS.results/DIRS.async
- Backward-compatible RESULTS_DIR/ASYNC_DIR aliases retained in types.ts
- Unit tests for ensureAccessibleDir + DIRS container (9 pass)

Refs: nicobailon/pi-subagents EPERM crash on Windows ACL corruption
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: 0511a836a1

ℹ️ 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 src/extension/index.ts
state.lastUiContext = ctx;

// Update DIRS to session-scoped paths to prevent cross-process conflicts
updateDirsForSession(sessionId);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restart watchers after changing session directories

When session_start mutates DIRS.results, the result watcher created earlier still closes over the pre-session path passed at registration time, so this later primeExistingResults() call continues scanning the old directory while new async runs write completion JSON under the session-scoped DIRS.results. In a normal session, those completions will not emit SUBAGENT_ASYNC_COMPLETE_EVENT, which can leave async notifications/result delivery and widget cleanup stuck; defer watcher creation until after the session directory is chosen or recreate/restart it with the new path.

Useful? React with 👍 / 👎.

Comment thread src/shared/types.ts
*/
export function updateDirsForSession(sessionId: string): string {
// Use first 8 chars of sessionId for a short, unique suffix
const sessionSuffix = sanitizeTempScopeSegment(sessionId.substring(0, 8));
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 Use a unique session suffix

resolveCurrentSessionId() prefers getSessionFile(), so in normal sessions this argument is a full path like .../sessions/<id>.jsonl; taking the first 8 characters means every session under the same path prefix gets the same suffix after sanitization. That defeats the session-scoped directory isolation for concurrent Pi processes in the same environment; derive the suffix from the basename, actual session id, or a hash of the full identity instead.

Useful? React with 👍 / 👎.

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