Skip to content

Commit 1f5001c

Browse files
authored
improvement(knip): check entry exports of private packages and delete their dead barrels (#8595)
* improvement(knip): check entry exports of private packages and delete their dead barrels - knip.jsonc: includeEntryExports on for every private package except db - delete the bare @sim/utils and @sim/workflow-persistence barrels and their "." exports - drop unused re-exports from the workflow-renderer and desktop-bridge barrels; un-export symbols only used in-file - delete 7 unreferenced emcn icons - baseline the remaining 262 entry-export findings (one-time rule expansion via --update --init) * improvement(packages): resolve the private-package exports the entry-export check exposed - Delete exports nothing uses: RadarChart, ChipModalPromptBody, InputOTPSeparator, DropdownMenuGroup/Portal, legacy terminal tool names, and dead types and helpers - Drop `export` from declarations used only in their own file, and remove barrel re-exports no consumer imports - Tag getOAuthClientCapabilityFields and generateRandomBytes `@public`: generate-docs loads the first by file path, and check:utils names the second - Trim the workflow-authz mock to the module's remaining exports - The unused-exports baseline gains no entries and drops one * fix(emcn): keep ChipTimePicker in the barrel as documented chip-family API * chore(emcn): export CVA variants only once another module composes them * chore(emcn): delete the PillsRing icon, unused since the generic resource panel lost its entry list * chore(knip): shrink the unused-exports baseline after rebasing onto staging
1 parent 55de876 commit 1f5001c

96 files changed

Lines changed: 236 additions & 1163 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.claude/rules/emcn-components.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from
1212

1313
Never hand-roll the chip pill from raw class strings (they go stale). Compose from the canonical sources:
1414

15-
- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFilledSurfaceTokens`, `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed.
15+
- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed.
1616
- **Pill geometry:** `chip/chip.tsx` — `chipVariants` (30px tall, `rounded-lg`, `px-2`, icon↔text `gap-1.5`). Every pill-shaped trigger (`ChipDropdown`, `ChipSelect`, `ChipSwitch`) reuses it for visual parity.
1717

1818
Canonical look: normal font-weight (never `font-medium`/`font-semibold`), value text `--text-body`, icons `--text-icon` at `size-[14px]`, placeholder `--text-muted`, `transition-colors`, **no focus ring** (the caret marks focus). Filled surface is `--surface-5` light / `--surface-4` dark with a `--border` border (`chip-chrome.ts` still spells it through the legacy alias `--border-1`; new code writes `--border`).
@@ -54,6 +54,6 @@ Declare keyboard intent on the action-owning primitive; never add document-level
5454
- **Discriminated-union props for modes** (e.g. `multiple`, the modal field `type`) instead of near-duplicate components.
5555
- **Delete legacy variants after migration** — leave no dead paths.
5656
- **Verify CSS vars exist.** An undefined var resolves to `currentColor`, which draws black borders. Align to the canonical tokens: normal weight, `--text-body`, `--text-icon`.
57-
- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example.
57+
- Use Radix UI primitives for accessibility. Export the component; export its CVA `variants` once another module composes them (`check:unused-exports` flags an export nothing imports). Document with TSDoc + a usage example.
5858

5959
Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating.

‎.cursor/rules/emcn-components.mdc‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Import components, `cn`, and tokens from the `@sim/emcn` barrel; icons come from
1313

1414
Never hand-roll the chip pill from raw class strings (they go stale). Compose from the canonical sources:
1515

16-
- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFilledSurfaceTokens`, `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed.
16+
- **Surface, typography + content tokens:** `chip/chip-chrome.ts` — `chipFieldSurfaceClass`, `chipFieldTextClass` (text fields and the dropdown search box build on these), plus the chip-content chrome `chipContentGap`, `chipGeometryClass`, `chipContentIconClass`, `chipContentLabelClass`, `cellIconNodeClass` (non-chip surfaces that must visually match chip content, e.g. resource table cells), and the row-state pair `chipHoverSurfaceClass` / `chipActiveSurfaceClass` (hover vs. selected — mutually exclusive, so a selected row holds its surface through hover; every hand-rolled row imports these rather than restating the literals). All are re-exported from the `@sim/emcn` barrel — no subpath import needed.
1717
- **Pill geometry:** `chip/chip.tsx` — `chipVariants` (30px tall, `rounded-lg`, `px-2`, icon↔text `gap-1.5`). Every pill-shaped trigger (`ChipDropdown`, `ChipSelect`, `ChipSwitch`) reuses it for visual parity.
1818

1919
Canonical look: normal font-weight (never `font-medium`/`font-semibold`), value text `--text-body`, icons `--text-icon` at `size-[14px]`, placeholder `--text-muted`, `transition-colors`, **no focus ring** (the caret marks focus). Filled surface is `--surface-5` light / `--surface-4` dark with a `--border` border (`chip-chrome.ts` still spells it through the legacy alias `--border-1`; new code writes `--border`).
@@ -55,6 +55,6 @@ Declare keyboard intent on the action-owning primitive; never add document-level
5555
- **Discriminated-union props for modes** (e.g. `multiple`, the modal field `type`) instead of near-duplicate components.
5656
- **Delete legacy variants after migration** — leave no dead paths.
5757
- **Verify CSS vars exist.** An undefined var resolves to `currentColor`, which draws black borders. Align to the canonical tokens: normal weight, `--text-body`, `--text-icon`.
58-
- Use Radix UI primitives for accessibility. Export the component and its `variants` (when using CVA). Document with TSDoc + a usage example.
58+
- Use Radix UI primitives for accessibility. Export the component; export its CVA `variants` once another module composes them (`check:unused-exports` flags an export nothing imports). Document with TSDoc + a usage example.
5959

6060
Color tokens and icon-size conventions are canonical in `.claude/rules/sim-styling.md` — follow it rather than restating.

‎CLAUDE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This file (also `AGENTS.md`) holds the repo-wide rules. Area detail lives in `.c
88
- **Logging**: `createLogger` from `@sim/logger`; `logger.info` / `logger.warn` / `logger.error`, never `console.log`. Inside `withRouteHandler` the logger already carries the request ID — no manual `withMetadata({ requestId })`.
99
- **Comments**: name things so the code explains itself. TSDoc documents exported APIs and non-obvious modules. An inline `//` is only for a terse, non-obvious *why*, or for a script-enforced `// <tag>: <reason>` annotation (`boundary-raw-fetch`, `double-cast-allowed`, `boundary-raw-json`, `untyped-response`, `rq-lint-allow`, `client-boundary-allow`, `utils-lint-allow`, …). History belongs in the commit message. No `====` separators or commented-out code (`check:comment-hygiene` enforces this). The `/you-might-not-need-a-comment` skill applies this to a diff.
1010
- **ID generation**: `generateId()` (UUID v4, the default) or `generateShortId(size?)` (URL-safe, 21 chars by default) from `@sim/utils/id` — never `crypto.randomUUID()`, `nanoid`, or `uuid`. Both use `crypto.getRandomValues()`, so they also work in non-secure (HTTP) browsers. For other randomness, `@sim/utils/random` (`randomInt`, `randomFloat`, `randomItem`, `generateRandomBytes`, `generateRandomHex`) — never `Math.random()` or `crypto.randomBytes()`.
11-
- **Common utilities**: use the shared helpers from `@sim/utils` instead of inline implementations (`check:utils` bans most of the inline forms below):
11+
- **Common utilities**: use the shared helpers from the `@sim/utils/<module>` subpaths instead of inline implementations (`check:utils` bans most of the inline forms below):
1212
- `sleep(ms)` from `@sim/utils/helpers` — never `new Promise(resolve => setTimeout(resolve, ms))`
1313
- `toError(e)` from `@sim/utils/errors` — normalize caught values to `Error`; never `e instanceof Error ? e : new Error(String(e))`
1414
- `getErrorMessage(e, fallback?)` from `@sim/utils/errors` — never `e instanceof Error ? e.message : 'fallback'`

‎apps/sim/lib/credentials/application/discover-managed-mcp-tools.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ vi.mock('@/lib/mcp/application/use-cases', () => mcpUseCasesMock)
4242
vi.mock('@/lib/workspaces/application/workspace-context', () => workspaceContextMock)
4343
vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock)
4444
vi.mock('@/lib/workflows/application/context', () => workflowContextMock)
45-
vi.mock('@sim/workflow-persistence', () => ({
45+
vi.mock('@sim/workflow-persistence/load', () => ({
4646
loadWorkflowFromNormalizedTablesRaw: hoisted.loadWorkflow,
4747
}))
4848

‎apps/sim/lib/mcp/application/execute-managed-tool.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const hoisted = vi.hoisted(() => ({
1818
saveToolSnapshot: vi.fn(),
1919
}))
2020

21-
vi.mock('@sim/workflow-persistence', () => ({
21+
vi.mock('@sim/workflow-persistence/load', () => ({
2222
loadWorkflowFromNormalizedTablesRaw: hoisted.loadWorkflow,
2323
}))
2424

‎apps/sim/lib/mcp/application/execute-tool.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const hoisted = vi.hoisted(() => ({
2525
getServer: vi.fn(),
2626
}))
2727

28-
vi.mock('@sim/workflow-persistence', () => ({
28+
vi.mock('@sim/workflow-persistence/load', () => ({
2929
loadWorkflowFromNormalizedTablesRaw: hoisted.loadWorkflow,
3030
}))
3131

‎apps/sim/lib/mcp/application/operation-access.test.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { queueTableRows, resetDbChainMock, schemaMock } from '@sim/testing'
33
import { beforeEach, describe, expect, it, vi } from 'vitest'
44

55
const { loadWorkflow } = vi.hoisted(() => ({ loadWorkflow: vi.fn() }))
6-
vi.mock('@sim/workflow-persistence', () => ({ loadWorkflowFromNormalizedTablesRaw: loadWorkflow }))
6+
vi.mock('@sim/workflow-persistence/load', () => ({
7+
loadWorkflowFromNormalizedTablesRaw: loadWorkflow,
8+
}))
79

810
import {
911
loadMcpOperationAccess,

‎apps/sim/lib/mcp/application/operation-access.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Principal } from '@sim/auth/principal'
22
import { db } from '@sim/db'
33
import { workflowDeploymentVersion } from '@sim/db/schema'
44
import { isPlainRecord } from '@sim/utils/object'
5-
import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence'
5+
import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence/load'
66
import { and, eq } from 'drizzle-orm'
77
import { OrchestrationError } from '@/lib/core/orchestration/types'
88
import {

‎apps/sim/stores/workflows/workflow/types.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export type {
3838
Variable,
3939
WorkflowState,
4040
}
41-
export { isValidSubflowType, SUBFLOW_TYPES } from '@sim/workflow-types/workflow'
41+
export { SUBFLOW_TYPES } from '@sim/workflow-types/workflow'
4242

4343
export interface WorkflowActions {
4444
updateNodeDimensions: (id: string, dimensions: { width: number; height: number }) => void

‎knip.jsonc‎

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44
// Unused exports, types, and duplicates are ratcheted by check:unused-exports,
55
// which reuses this config in the same knip pass.
66
"include": ["files", "dependencies", "unlisted", "unresolved"],
7-
// knip's default, stated so it is a decision: no entry file's exports are reported.
8-
// That keeps package `exports`/`main`/`bin` contracts (ts-sdk, emcn, cli, …) and framework
9-
// entries (Next routes, Trigger tasks) public, and also exempts the other configured entries
10-
// (scripts, `*.integration.ts`, `background/**`, desktop and SDK examples).
11-
"includeEntryExports": false,
7+
// On by default: every workspace's `exports` map serves only this monorepo, so an entry export
8+
// no workspace imports is dead. The workspaces below turn it off because their entries are
9+
// public or standalone: the apps (framework entries such as Next routes and Trigger tasks), the
10+
// published packages (cli, sim-cli, sim-setup, ts-sdk), db (standalone scripts), and the root
11+
// (scripts). A new private package is checked without opting in.
12+
"includeEntryExports": true,
1213
"workspaces": {
1314
".": {
15+
"includeEntryExports": false,
1416
"entry": ["scripts/**/*.{ts,tsx}", "vitest.shared.ts"],
1517
"paths": { "@/*": ["./apps/sim/*"] },
1618
// This alias selects the native tsc binary; see check-native-typecheck.ts.
1719
"ignoreDependencies": ["@typescript/native"]
1820
},
1921
"apps/sim": {
22+
"includeEntryExports": false,
2023
"entry": [
2124
// Container bootstrap and Trigger's directory-discovered task graph.
2225
"bootstrap.ts",
@@ -69,8 +72,9 @@
6972
// Live test spawns this path with cwd=MSHIP_WORKER_ROOT (a sibling repo).
7073
"ignoreUnresolved": ["tools/probes/src/controller-run-read.ts"]
7174
},
72-
"apps/realtime": { "entry": ["src/bootstrap.ts"] },
75+
"apps/realtime": { "includeEntryExports": false, "entry": ["src/bootstrap.ts"] },
7376
"apps/desktop": {
77+
"includeEntryExports": false,
7478
// scripts/build.ts and e2e/updater.spec.ts supply these to esbuild by path.
7579
"entry": [
7680
"src/main/index.ts",
@@ -83,24 +87,30 @@
8387
// ensure-pty-prebuilds.ts assembles these package names for universal builds.
8488
"ignoreDependencies": ["@lydell/node-pty-darwin-arm64", "@lydell/node-pty-darwin-x64"]
8589
},
90+
"apps/docs": { "includeEntryExports": false },
91+
"apps/pii": { "includeEntryExports": false },
92+
"packages/cli": { "includeEntryExports": false },
8693
"packages/db": {
94+
"includeEntryExports": false,
8795
"entry": [
8896
"scripts/*.ts",
8997
"script-migrations/*.ts",
9098
"**/*.integration.ts",
9199
"vitest.integration.setup.ts"
92100
]
93101
},
94-
"packages/sim-cli": {
95-
"entry": ["src/index.ts", "src/runtime.ts", "scripts/*.ts"]
96-
},
97-
"packages/ts-sdk": { "entry": ["examples/*.ts"] },
98102
// The contract audit reads this snapshot by filename.
99103
// Generated, so its export surface is not ratcheted either.
100104
"packages/desktop-bridge": {
101105
"entry": ["contract-snapshot.ts"],
102106
"ignoreIssues": { "contract-snapshot.ts": ["exports", "types", "duplicates"] }
103107
},
108+
"packages/sim-cli": {
109+
"includeEntryExports": false,
110+
"entry": ["src/index.ts", "src/runtime.ts", "scripts/*.ts"]
111+
},
112+
"packages/sim-setup": { "includeEntryExports": false },
113+
"packages/ts-sdk": { "includeEntryExports": false, "entry": ["examples/*.ts"] },
104114
// This shared config is consumed by apps that own the Next dependency.
105115
"packages/tsconfig": { "ignoreUnresolved": ["next"] }
106116
}

0 commit comments

Comments
 (0)