Skip to content

Add Knip#1707

Open
shivamhwp wants to merge 13 commits intopingdotgg:mainfrom
shivamhwp:add-knip
Open

Add Knip#1707
shivamhwp wants to merge 13 commits intopingdotgg:mainfrom
shivamhwp:add-knip

Conversation

@shivamhwp
Copy link
Copy Markdown
Collaborator

@shivamhwp shivamhwp commented Apr 3, 2026

What Changed

This PR adds Knip to the repo in a minimal setup-only pass.

It introduces:

  • knip as a root dev dependency
  • a root bun run knip script
  • a monorepo-aware knip.json covering the apps, packages, and scripts workspaces

This PR does not include any dead-code cleanup. It just wires Knip in so the current baseline is visible from CI/local runs.

Why

The earlier branch mixed Knip setup with a much larger cleanup/rebase diff. This resets the work to a small, reviewable PR that only adds the tool and its config.

Knip currently reports existing unused files, dependencies, exports, and types in the repo. That cleanup can happen in follow-up PRs once the config is accepted.

Changes

What This PR Actually Changes

  • Adds a real Knip setup for this monorepo and cleans up dependency classification so knip, knip --production, and knip --strict are meaningful.
  • Removes genuinely dead code: unused UI primitives, dead web helpers, dead observability files, and stale server error/schema modules.
  • Shrinks runtime module surface by moving pure/test-only logic into *.shared.ts, *.logic.ts, and *.testing.ts modules instead of exporting internals from production files.
  • Moves integration-only checkpoint support out of production src/ and into integration support.
  • Fixes merge/review fallout so the cleanup stays aligned with current main behavior.
Notable dead code removed
  • apps/web/src/components/ui/card.tsx
  • apps/web/src/components/ui/field.tsx
  • apps/web/src/components/ui/fieldset.tsx
  • apps/web/src/components/ui/form.tsx
  • apps/web/src/components/ui/input-group.tsx
  • apps/web/src/components/ui/kbd.tsx
  • apps/web/src/components/ui/radio-group.tsx
  • apps/web/src/historyBootstrap.ts
  • apps/web/src/rpc/client.ts
  • apps/server/src/orchestration/Errors.ts
  • apps/server/src/orchestration/Schemas.ts
  • apps/server/src/persistence/Errors.ts
  • dead observability tracing/file-sink files under apps/server/src/observability/
Server cleanup
  • Split runtime vs shared logic in:
    • keybindings.ts -> keybindings.logic.ts
    • open.ts -> open.logic.ts / open.shared.ts
    • cli.ts -> cli.logic.ts
    • bootstrap.ts -> bootstrap.shared.ts
    • serverRuntimeStartup.ts -> serverRuntimeStartup.logic.ts
    • codexAppServerManager.ts -> codexAppServerManager.shared.ts
  • Extracted large pure logic from:
    • git/Layers/GitCore.ts -> GitCore.shared.ts
    • terminal/Layers/Manager.ts -> Manager.shared.ts
    • provider layers into ClaudeProvider.logic.ts / CodexProvider.shared.ts
  • Moved checkpoint-only support into apps/server/integration/support/ProjectionCheckpoints.ts
  • Kept provider metrics instrumentation that runtime/tests still rely on
Web cleanup
  • Split pure store logic from runtime stores:
    • store.ts -> store.logic.ts
    • uiStateStore.ts -> uiStateStore.logic.ts
  • Split shared/test-only helpers from runtime modules:
    • sidebar logic
    • terminal drawer logic
    • keybindings
    • terminal context
    • pending user input
    • composer draft store
    • local storage/settings helpers
    • desktop update/timestamp helpers
  • Moved test-only reset helpers out of runtime modules:
    • rpc/atomRegistry.testing.ts
    • nativeApi.testing.ts
  • Fixed current-main drift in timeline/sidebar/settings/root route typing and helper boundaries

Behavior

  • No intended user-facing behavior change.
  • The cleanup is about deleting dead code and tightening module boundaries, not changing routes, websocket contracts, storage keys, provider semantics, or DB behavior.

Validation

  • bun fmt
  • bun lint
  • bun typecheck
  • bun run test
  • bun run knip
  • bun run knip -- --production
  • bun run knip -- --strict

All pass.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Medium Risk
Moderate risk due to refactoring core server plumbing (CLI config resolution and GitCore implementation) and changing boolean flag precedence, which could affect runtime defaults and git operations if behavior diverges from the previous implementation.

Overview
Refactors server code to reduce runtime module surface by extracting reusable/test-only logic into new *.shared.ts, *.logic.ts, and *.testing.ts modules (e.g., bootstrap.shared.ts, cli.logic.ts, codexAppServerManager.shared.ts, and git/Layers/GitCore.shared.ts).

Updates CLI config resolution to centralize precedence handling and ensure explicit false flags override env/bootstrap values, with new test coverage. Integration tests are adjusted to use Sqlite.testing.ts, move projection checkpoint repository support into integration/support, and shorten default wait timeouts.

Minor cleanup includes reclassifying workspace deps as runtime dependencies in app package.json files and narrowing a couple of exported TS interfaces/constants to internal-only types.

Written by Cursor Bugbot for commit eaf00af. This will update automatically on new commits. Configure here.

Note

Add Knip to remove unused exports and dead code across the monorepo

  • Adds Knip for dead code and unused export detection, configured via knip.json with per-workspace entry/project globs.
  • Resolves Knip findings by removing or internalizing hundreds of unused exports across apps/web, apps/server, and packages/contracts, including types, interfaces, constants, and helper functions.
  • Extracts shared logic into new .shared.ts modules (e.g. terminalContext.shared.ts, Sqlite.shared.ts, cli.logic.ts, keybindings.logic.ts) so that previously-exported internals can remain accessible to tests without polluting public APIs.
  • Adds companion .testing.ts modules for test-only helpers that were previously exported from production modules.
  • Trims the components/ui library surface significantly — many sub-components (e.g. AlertDialogTrigger, AutocompleteInput, DropdownMenu* aliases, SheetPanel) are removed from their respective modules.
  • Moves @t3tools/contracts and @t3tools/shared from devDependencies to dependencies in apps/desktop and apps/server.
  • Risk: any downstream code importing the removed/internalized exports will break at compile time; the changes are intentional but wide-reaching.
📊 Macroscope summarized eaf00af. 83 files reviewed, 7 issues evaluated, 3 issues filtered, 2 comments posted

🗂️ Filtered Issues

apps/server/src/git/Layers/GitCore.shared.ts — 0 comments posted, 2 evaluated, 1 filtered
  • line 161: For type 2 (rename/copy) entries in porcelain v2 output, the code extracts the original path (after the tab) instead of the new path (before the tab). Git porcelain v2 format is 2 ... <path>\t<origPath> where <path> is the new destination. The code does line.slice(tabIndex + 1) which gets <origPath>. This causes renamed files to be recorded with their old path, creating inconsistency with parseNumstatEntries which correctly extracts the new path, potentially causing duplicate entries or mismatched file tracking. [ Out of scope (triage) ]
apps/server/src/provider/Layers/ClaudeProvider.logic.ts — 1 comment posted, 2 evaluated, 1 filtered
  • line 223: In findSubscriptionType, nested arrays under container keys are silently skipped. At line 224-227, asRecord(record[key]) returns None when record[key] is an array (due to the !globalThis.Array.isArray(v) check in asRecord), so the array is never searched. This contradicts the function's stated intent to "Walk an unknown parsed JSON value" since arrays are only handled at the top level (line 212-214), not when nested under keys like "account" or "subscription". If the CLI outputs JSON like {"account": [{"subscriptionType": "max"}]}, detection will fail. The fix would be to call findSubscriptionType(record[key]) directly instead of wrapping with asRecord().pipe(Option.flatMap(findSubscriptionType)). [ Out of scope (triage) ]
apps/web/src/store.logic.ts — 0 comments posted, 1 evaluated, 1 filtered
  • line 101: In mapSession, line 101 assigns session.updatedAt to the createdAt field. This causes createdAt and updatedAt to always have the same value, losing the actual creation timestamp. If OrchestrationSession has a createdAt property, it should be used here instead. [ Failed validation ]

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0495c7d6-d0d3-43a3-9ffe-aa6bac9447cc

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Apr 3, 2026
@shivamhwp shivamhwp changed the title Add Knip config Add Knip Apr 3, 2026
},
"packages/shared": {
"entry": [
"src/{model,git,logging,shell,Net,DrainableWorker,KeyedCoalescingWorker,schemaJson,Struct,String}.ts!",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing serverSettings from shared package entry list

Low Severity

The packages/shared entry pattern explicitly enumerates every production export from package.json (model, git, logging, shell, Net, DrainableWorker, KeyedCoalescingWorker, schemaJson, Struct, String) but omits serverSettings, which is both exported in packages/shared/package.json and actively imported by apps/desktop and apps/server. While Knip auto-discovers entries from package.json exports, the explicit brace-expansion list creates a false impression of completeness that could mislead future maintainers.

Fix in Cursor Fix in Web

shivamhwp added 11 commits April 3, 2026 14:02
- narrow module surface areas by making internal types and constants private
- drop stale exports, helpers, and UI code no longer used
- reduce unused dependencies and simplify server/web modules
- Move shared workspace deps into runtime packages
- Hide internal schema helpers and rename turn diff contract
- Remove obsolete web history bootstrap module
- Extract shared bootstrap, open, keybinding, and receipt logic
- Move integration-only projection checkpoint repository support
- Update tests and web helpers to use the new shared modules
- Split common server, git, persistence, and UI helpers into shared/testing modules
- Reduce duplication across tests and runtime code
- Keep integration and provider flows wired to the new shared layers
- Re-export SQLite and keybinding helpers from shared modules
- Adjust git branch listing and localStorage fallback behavior
- Stabilize MessagesTimeline tests with a mocked markdown component
- Export Claude auth/status helpers from `ClaudeProvider`
- Remove the separate testing-only Claude provider module
- Update provider registry tests to import the shared implementation
- move CLI config resolution into `cli.logic.ts`
- tighten git upstream refresh handling and remote parsing
- update tests and web/server plumbing for the refactor
- Move shared Codex provider helpers into `CodexProvider.shared`
- Add tests for custom model_provider parsing and auth status JSON handling
macroscopeapp[bot]
macroscopeapp bot previously approved these changes Apr 3, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 3, 2026

Approvability

Verdict: Needs human review

Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

You can customize Macroscope's approvability policy. Learn more.

- remove obsolete trace sink and tracer layers
- add observability config plumbing and branch pagination updates
- align tests with the new server and Git status shape
@github-actions github-actions bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Apr 3, 2026
@macroscopeapp macroscopeapp bot dismissed their stale review April 3, 2026 12:35

Dismissing prior approval to re-evaluate eaf00af

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

}

const resolveBooleanFlag = (flag: Option.Option<boolean>, envValue: boolean) =>
Option.getOrElse(flag, () => envValue);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Inconsistent resolveBooleanFlag semantics across codebase

Medium Severity

The resolveBooleanFlag in cli.logic.ts dropped the Option.filter(flag, Boolean) call that existed in the original cli.ts, changing its semantics: Some(false) now returns false instead of falling through to envValue. While the new behavior is arguably more correct (and a new test validates it), the identical function in scripts/build-desktop-artifact.ts still uses the old Option.filter(flag, Boolean) pattern. These two copies now silently disagree on how explicit false flags are handled, which is likely to cause confusion or incorrect behavior when one is updated but not the other.

Fix in Cursor Fix in Web

Comment on lines +46 to +63
export function parseKeybindingShortcut(value: string): KeybindingShortcut | null {
const rawTokens = value
.toLowerCase()
.split("+")
.map((token) => token.trim());
const tokens = [...rawTokens];
let trailingEmptyCount = 0;
while (tokens[tokens.length - 1] === "") {
trailingEmptyCount += 1;
tokens.pop();
}
if (trailingEmptyCount > 0) {
tokens.push("+");
}
if (tokens.some((token) => token.length === 0)) {
return null;
}
if (tokens.length === 0) return null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Low src/keybindings.logic.ts:46

Empty string or whitespace-only input to parseKeybindingShortcut returns a shortcut for the + key instead of null. For input "": split("+") yields [""], the while loop pops it and pushes "+", so the function returns { key: "+", ... } rather than rejecting the invalid input.

 export function parseKeybindingShortcut(value: string): KeybindingShortcut | null {
+  const trimmed = value.trim();
+  if (trimmed.length === 0) {
+    return null;
+  }
   const rawTokens = value
     .toLowerCase()
     .split("+")
     .map((token) => token.trim());
🤖 Copy this AI Prompt to have your agent fix this:
In file apps/server/src/keybindings.logic.ts around lines 46-63:

Empty string or whitespace-only input to `parseKeybindingShortcut` returns a shortcut for the `+` key instead of `null`. For input `""`: `split("+")` yields `[""]`, the while loop pops it and pushes `"+"`, so the function returns `{ key: "+", ... }` rather than rejecting the invalid input.

Evidence trail:
apps/server/src/keybindings.logic.ts lines 46-99 at REVIEWED_COMMIT. The function `parseKeybindingShortcut` at line 46 processes empty string by: split("+") yields [""], while loop pops it (line 53-56), then pushes "+" (line 58), validation checks pass (lines 59-61), and the "+" token becomes the key in the default case (line 94-96), returning { key: "+", ... } instead of null.

auth: extractAuthBoolean(JSON.parse(trimmed)),
};
} catch {
return { attemptedJsonParse: false as const, auth: undefined as boolean | undefined };
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Low Layers/ClaudeProvider.logic.ts:140

When JSON.parse throws on malformed JSON, attemptedJsonParse is incorrectly set to false in the catch block, causing the function to fall through to the result.code === 0 check and return status: "ready" / auth: { status: "authenticated" } even though the auth status could not be verified. The catch block should set attemptedJsonParse: true since parsing was attempted but failed.

-      return { attemptedJsonParse: false as const, auth: undefined as boolean | undefined };
🤖 Copy this AI Prompt to have your agent fix this:
In file apps/server/src/provider/Layers/ClaudeProvider.logic.ts around line 140:

When `JSON.parse` throws on malformed JSON, `attemptedJsonParse` is incorrectly set to `false` in the catch block, causing the function to fall through to the `result.code === 0` check and return `status: "ready"` / `auth: { status: "authenticated" }` even though the auth status could not be verified. The catch block should set `attemptedJsonParse: true` since parsing was attempted but failed.

Evidence trail:
apps/server/src/provider/Layers/ClaudeProvider.logic.ts lines 130-167 at REVIEWED_COMMIT. The catch block at line 140 sets `attemptedJsonParse: false`. Following the control flow: if `auth` is undefined and `attemptedJsonParse` is false, lines 144, 147, and 153 all skip, and line 160's `if (result.code === 0)` returns `status: 'ready', auth: { status: 'authenticated' }` even though JSON parsing failed and auth status is unknown.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant