Skip to content

feat(applications): banner when editor IntelliSense degrades#1528

Open
dawsontoth wants to merge 3 commits into
stagefrom
claude/intellisense-degradation-banner-c3cffd
Open

feat(applications): banner when editor IntelliSense degrades#1528
dawsontoth wants to merge 3 commits into
stagefrom
claude/intellisense-degradation-banner-c3cffd

Conversation

@dawsontoth

Copy link
Copy Markdown
Contributor

Summary

Closes #1504. When the Applications code editor silently degrades its language features to stay responsive, it now tells the user with a dismissible in-editor banner instead of only logging to the console. Follow-up to #1499/#1500 — that work added the safety bound and a developer-facing console.warn/console.debug; this is the user-facing half raised in review.

Two degradation modes are surfaced:

  • Type-acquisition budget exhausted — once cumulative acquired @types reach MAX_EXTRA_LIB_CHARS_TOTAL and ExtraLibBudget seals, further packages aren't acquired and their imports report a spurious "cannot find module".
  • Oversized file → plaintext — a file over MAX_WORKER_MODEL_CHARS (512 KB) renders as plaintext with no highlighting or language features.

What changed

  • typeAcquisition.ts: new isTypeAcquisitionBudgetSpent() surfaces the sealed-budget signal (previously console-only).
  • useApplicationTypeIntelligence.ts: now returns { typeAcquisitionBudgetExhausted } — seeded from the module-level budget (so a session that already exhausted it shows the notice immediately) and refreshed after each acquisition pass.
  • DegradedIntelliSenseBanner.tsx (new): a thin, dismissible notice with role="status" / aria-live="polite".
  • TextEditorView/index.tsx: computes the active degradation (oversized wins; budget notice only on editable JS/TS files) and renders the banner above the editor. Dismissal is keyed per path:variant, so it re-shows for a different file or degradation but stays dismissed for the current one.

Design notes (matches the issue)

  • Non-blocking, dismissible, and sits flush below the toolbar (mt-9 = the 36px ContentActions overlay) so it never covers the first line of code.
  • Subtle inline bar (amber), not a modal/toast — it reflects a persistent state.
  • Announced via role="status" / aria-live="polite".

Wrapping the editor in a flex column required giving that column a definite height (h-full, not min-h-full) plus a flex-1 min-h-0 box — otherwise @monaco-editor/react's height:100% can't resolve and Monaco collapses to a few pixels.

Testing

  • New unit test DegradedIntelliSenseBanner.test.tsx (copy, aria-live="polite", dismiss callback); workerLimits tests still green.
  • tsc -b, oxlint, dprint all clean.
  • Browser-verified on stage data (Applications editor, real Monaco): with the banner forced on, it renders flush below the toolbar, the editor fills the pane (1043px), and the first line of code sits below the banner; dismissing removes it and the editor reflows to full height (1136px, padding.top restored to 48). With the trigger removed, no banner appears for a normal file — no regression.

🤖 Generated with Claude Code

Closes #1504. Follow-up to #1500, which added the safety bound and a
console-only breadcrumb; this surfaces the same degradation to the user.

Two silent degradations now show a dismissible notice above the editor:

- Type-acquisition budget exhausted: once the session-wide @types budget
  seals (ExtraLibBudget.isSpent), further packages report a spurious
  "cannot find module". A new isTypeAcquisitionBudgetSpent() surfaces the
  signal, and useApplicationTypeIntelligence now returns it as status.
- Oversized file: a file over MAX_WORKER_MODEL_CHARS renders as plaintext
  (the existing `oversized` flag).

The notice is a thin bar (role="status", aria-live="polite") sitting flush
below the toolbar so it never covers the first line of code; dismissal is
keyed per file+mode so it re-shows for a different file/degradation.

Wrapping the editor in a flex column needs a definite-height column
(h-full) and a flex-1/min-h-0 box, or Monaco's height:100% fails to
resolve and the editor collapses to a few px.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dawsontoth
dawsontoth requested a review from a team as a code owner July 16, 2026 18:28
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 50.64% 5339 / 10541
🔵 Statements 51.22% 5718 / 11162
🔵 Functions 42.76% 1306 / 3054
🔵 Branches 44.04% 3585 / 8139
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/features/instance/applications/components/TextEditorView/DegradedIntelliSenseBanner.tsx 100% 100% 100% 100%
Generated in workflow #1532 for commit 6e5b62f by the Vitest Coverage Report Action

"Reopening the tab resets this" is misleading: the app references more
packages than the type budget can hold, so it would just re-throttle.
Explain the cause instead of promising a fix that won't hold.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a 'DegradedIntelliSenseBanner' component to notify users when the editor's language features are limited due to session-wide type-acquisition budget exhaustion or oversized files. The changes include updating the 'useApplicationTypeIntelligence' hook to track and expose the budget status, and integrating the banner into the 'TextEditorView' component. I have kept the review comment regarding the extraction of inline prop types into a dedicated interface as it improves code maintainability and readability.

Address PR #1528 review: extract the inline prop type into an exported
DegradedIntelliSenseBannerProps interface.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

const MESSAGES: Record<IntelliSenseDegradation, string> = {
budget:
'Type information is limited to keep the editor responsive — this application references more packages than the editor can load, so some imports may show “cannot find module.”',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Low: budget copy attributes a session-wide limit to "this application"

The @types budget is session-wide and monotonic across every project opened in the tab (see ExtraLibBudget / the isTypeAcquisitionBudgetSpent JSDoc). If a large app exhausts it, then opening a small app — which references few packages — still shows this banner claiming "this application references more packages than the editor can load." That's inaccurate for the small app; the budget was spent elsewhere. The linked issue's suggested copy is session-scoped for this reason ("limited in this session… Reopening the tab resets this").

Suggested fix:

Suggested change
'Type information is limited to keep the editor responsive — this application references more packages than the editor can load, so some imports may show “cannot find module.”',
'Type information is limited in this editor session to keep it responsive, so some imports may show “cannot find module.” Reopening the tab resets this.',


Generated by Barber AI

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Most people have one app, so the suggested text is more likely to be a bad experience for them.

@dawsontoth
dawsontoth requested a review from cb1kenobi July 16, 2026 20:58
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.

[Editor] Show an in-editor banner when IntelliSense is degraded (type-acquisition budget / oversized file)

2 participants