refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

refactor(plugin-gantt): drop three unread declarations from GanttView - #7522

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues
Sep 3, 2026
Merged

refactor(plugin-gantt): drop three unread declarations from GanttView#7522
os-project-manager merged 1 commit into
mainfrom
claude/issue-7512-ganttview-residues

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes#7512

Deletes three declarations (four bindings) from packages/plugin-gantt/src/GanttView.tsx that nothing read. Option A of the three the card offered, on the maintainer's ruling. 4 deletions, 0 insertions in source.

-const HEADER_HEIGHT = 50;-const COLUMN_WIDTH = 100; // Time column width- const [currentDate, setCurrentDate] = React.useState(() => tzShift.now());

Two different classes, not one

The card and this PR keep them apart deliberately:

  • HEADER_HEIGHT / COLUMN_WIDTH are lazy module constants. An unread module binding costs nothing at runtime, so removing them changes no behaviour whatsoever. Their cost was purely as a false signal — COLUMN_WIDTH = 100 sits beside code whose live column width is 110.
  • const [currentDate, setCurrentDate] = React.useState(...) was live. Every mount allocated a state slot and executed the tzShift.now() initializer, while neither the value nor the setter was ever referenced. Removing it has a real (if tiny) runtime effect — and no observable one: nothing rendered from the value and nothing could call the setter, so no output, prop, or timing a consumer can see moves.

Lumping these into one sentence of "all dead code" would misstate the second.

Readings, re-measured on this PR's base (a27d153c2)

Every zero below was taken with a declaration-form probe and a whole-word read-site probe run separately, each with a control that lit up in the same run.

symboldeclaration formwhole-word hits, repo-widecontrol lit in the same run
HEADER_HEIGHT1 (line 43)1 file, 1 line — its own declarationgit grep -lw RESIZE_EDGE_PX returned 2 files
COLUMN_WIDTH1 (line 44)1 line in GanttView.tsx; 8 / 5 / 4 lines in three sibling test files, each of which declares its ownconst COLUMN_WIDTH = 110 and imports nothing (verified: 0 import lines mentioning the name in all three)same run listed TASK_LIST_MIN_W at 7 lines
currentDate1 (line 873)1 line in plugin-gantt. The 60-odd other hits are all plugin-calendar plus packages/types — that currentDate is the CalendarSchema authorable key (packages/types/src/complex.ts:261), a different binding entirelytzShift lit at 27 lines in the same file
setCurrentDate1 (line 873)1 line in plugin-gantt; 2 in plugin-calendar/src/ObjectCalendar.tsxas above

Published surface: none of the four moves.grep -nE 'export.*(HEADER_HEIGHT|COLUMN_WIDTH|currentDate|setCurrentDate)' over the file returns 0, with two controls lit in the same run: export const MS_PER_DAY matched, and the export { block query matched 3 lines in src/index.tsx. The file has no trailing re-export block at all (its last line is the component's closing brace), and index.tsx re-exports GanttView by name, so no export * chain could carry a non-exported binding out. Two are module-scope, two are function-scope inside GanttView. No published symbol, prop, type, zod schema or spec key changes.

tzShift keeps 27 whole-word readers in the file after the deletion, so its import stays live — the error-severity unused-import rule is not in play here.

Reverse verification — ESLint, with a control that stays put

There is no honest behaviour pin to add for the removal of four bindings with zero readers, so the red/green is ESLint. Package-level eslint . in packages/plugin-gantt, before and after, --format json, exit code captured before any pipe (both runs exited 0 — this package is warning-only):

files lintedproblemserrorswarningsGanttView.tsx
before (a27d153c2)92354035417
after (d4b093cd2)92350035013

Exactly four messages disappeared, and none appeared:

-1 @typescript-eslint/no-unused-vars :: 'HEADER_HEIGHT' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'COLUMN_WIDTH' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'currentDate' is assigned a value but never used.
-1 @typescript-eslint/no-unused-vars :: 'setCurrentDate' is assigned a value but never used.

The control that stays in place — same rule, same file, deliberately untouched:

before line 2323:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.
after line 2319:9 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used.

It survives and shifts by exactly 4 lines, matching the 4 deleted lines. That tombstone belongs to objectui#7421 / PR objectui#7511 and is not touched here; objectui#7421 stays open for it.

Baseline note

The card quotes 16 warnings for this file and 353 for the package; this PR's base a27d153c2 measures 17 and 354. The difference is exactly the taskListWidth_LEGACY_REMOVED warning above — the card's figures were taken on a tree where PR objectui#7511 had already removed the tombstone, and that PR had not landed on main when this branch was cut. Every other figure in the card reproduced exactly.

Verification run, all at d4b093cd2

Heavy steps went through the shared verify lock.

  • pnpm exec eslint . in packages/plugin-gantt — exit 0, 350 problems / 0 errors (table above)
  • pnpm --filter @object-ui/plugin-gantt run type-check (tsc --noEmit && tsc -p tsconfig.test.json) — exit 0, after pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-gantt^...' build (the first attempt failed only with TS2307: Cannot find module '@object-ui/components' — unbuilt dependency closure in a fresh worktree, not a finding)
  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2, from the repo root — Test Files 62 passed (62), Tests 485 passed (485)
  • node scripts/check-changeset-presence.mjs — exit 0, accepts the empty-frontmatter declaration
  • node scripts/check-changeset-fixed.mjs, node scripts/check-changeset-no-major.mjs — exit 0
  • node scripts/check-control-bytes.mjs — exit 0 (6195 tracked text files scanned), plus a targeted control-byte grep over the two changed files: clean

Lint scope was narrowed to this package, and here is the proof the narrowing excludes nothing. (1) The universe came from ESLint's own config, not a guess: eslint . resolved the package's file set itself. (2) The count is read from --format json — 92 entries, identical in both runs. (3) The config cannot carry a verdict across files: grep -nE 'projectService|parserOptions|project:' eslint.config.js returns 0 (control: the same grep shape returns 9 lines for files:|ignores: in that same file), so type-aware linting is not enabled and a deletion inside one .tsx cannot move any untouched file's result. The added .changeset/*.md is outside ESLint's files: ['**/*.{ts,tsx}'] entirely.

Not measured here:node scripts/check-readme-exports.mjs exits 1 in this worktree, but all 312 messages read type entry ./dist/index.d.ts is not on disk -- run pnpm build first — the gate needs a full workspace build that this worktree does not have. That is a missing prerequisite, not a red gate; CI builds first and measures it there. None of the four deleted bindings appears in any README, since none was exported.

Changeset

Empty frontmatter (.changeset/7512-ganttview-unread-residues.md), which this repo treats as the explicit "releases nothing" declaration rather than an omission. Justification: plugin-gantt source changed, so the presence gate demands a declaration; but no published symbol, prop, type or rendered output moves, and the one binding with a runtime cost had no observable effect. Same shape as PR objectui#7511.

Out of scope

columnWidthForContainer is untouched. Its three arms all return 110, which is what made COLUMN_WIDTH = 100 misleading — but that is objectui#7228's subject, and objectui#7228 remains open. Lifting @typescript-eslint/no-unused-vars to error (the card's option C) was ruled out for this unit of work; the package still carries 350 warnings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

`GanttView.tsx` carried three declarations (four bindings) that nothing read:
- `HEADER_HEIGHT` and `COLUMN_WIDTH` — module-level constants with zero
readers repo-wide. Lazy bindings: removing them has no runtime effect.
- `const [currentDate, setCurrentDate] = React.useState(() => tzShift.now())`
— not the same class. This one allocated a state slot and ran the
`tzShift.now()` initializer on every mount while neither binding was ever
referenced, so removing it does have a (tiny) runtime effect — and no
observable one, since nothing rendered from it and nothing could set it.
None of the four were exported. `tzShift` keeps 27 other readers in the file,
so its import stays live.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 50 chunks)3181.9 KB3191.4 KB
Main entry chunk (gzip)143.2 KB350 KB
Entry fileindex-BTO-H-yr.js
StatusPASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)15.67KB5.75KB
app-shell (runtime-config.js)20.68KB7.36KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)516.19KB117.80KB
core (index.js)6.12KB2.42KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)178.20KB49.60KB
fields (index.js)242.42KB61.26KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)34.34KB9.17KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.98KB10.98KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)48.12KB13.34KB
plugin-charts (index.js)70.87KB19.72KB
plugin-chatbot (index.js)196.19KB46.43KB
plugin-dashboard (index.js)132.82KB34.64KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)251.07KB64.12KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)132.87KB32.66KB
plugin-gantt (index.js)167.46KB41.06KB
plugin-grid (index.js)209.25KB56.71KB
plugin-kanban (index.js)52.71KB14.55KB
plugin-list (index.js)113.33KB27.60KB
plugin-map (index.js)20.55KB6.80KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)30.84KB8.85KB
plugin-tree (index.js)9.40KB3.23KB
plugin-view (index.js)85.22KB20.93KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)81.07KB26.86KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.63KB1.70KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.74KB2.25KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)8.11KB3.32KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@os-project-manager
os-project-manager marked this pull request as ready for review September 3, 2026 16:45
@os-project-manager
os-project-manager added this pull request to the merge queueSep 3, 2026
Merged via the queue into main with commit 78a3cc2Sep 3, 2026
34 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-7512-ganttview-residues branch September 3, 2026 17:02
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): three more declared-and-never-read residues sit in GanttView.tsx beside the tombstone #7421 removed

2 participants

@os-project-manager@claude