Skip to content

chore(knip): ignore submodule + remove orphaned dead code (#110) - #115

Merged
alex-mextner merged 5 commits into
mainfrom
chore/knip-cleanup
Jul 1, 2026
Merged

chore(knip): ignore submodule + remove orphaned dead code (#110)#115
alex-mextner merged 5 commits into
mainfrom
chore/knip-cleanup

Conversation

@alex-mextner

Copy link
Copy Markdown
Owner

Why

Resolve knip ticket #110. knip was flagging ~35 real items drowned under 279 false-positive ZenPlugins-submodule "unused files" (no knip config existed). Every flag was investigated via git log -S + introducing-commit history before acting — per the repo's "never delete dead code without investigation" rule.

What

  • knip.jsonc added: excludes the ZenPlugins/ submodule (mirrors biome), declares entry points (scripts/, libs/, barrels), ignoreExportsUsedInFile, and allowlists documented below.
  • Deleted (orphaned-by-migration, with evidence):
    • AgentEvent type — its agent.ts consumer was removed in 5e57a49 when it moved to AgentStreamWriter.
    • jsqr dependency — replaced by qr in 25d16da; zero source refs.
  • Kept + allowlisted with reason: GroupSpreadsheet (@public row type), zenmoney-types mirror (deliberate local copy per CLAUDE.md), pino-pretty (runtime pino transport, invisible to static analysis), and exports used only within their own file (createBot, CATEGORY_EMOJIS, aiDebugLogger, etc.) via ignoreExportsUsedInFile.

Results

knip exit 0 (clean), type-check + biome lint clean, full suite 3617/3617. No behavior change beyond the two orphaned removals (tests green confirm nothing referenced them).

Closes #110

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rq7c53bgYsq6uZ9hmdhXu9

knip had no config, so it scanned everything and drowned ~30 bot-own
flags under the ZenPlugins submodule noise plus dozens of false-positive
"unused files" (scripts, bank-sync.ts, tests, miniapp) that it could not
reach without declared entry points.

Config decisions:
- entry: bank-sync.ts (2nd PM2 process), ecosystem.config.cjs, scripts/**,
  src/**/*.test.ts, and the two module public-API barrels (dev-pipeline,
  analytics/ta) that are the intended import surface.
- project: exclude src/services/bank/ZenPlugins/** exactly like biome.jsonc
  ("!..."); the bot mirrors the types it needs locally.
- ignore: zenmoney-types.ts (deliberate local mirror of ZenMoney submodule
  types, intentionally complete) and src/test-utils/** (shared test helpers
  imported ad-hoc by tests, per the no-real-network test rule).
- ignoreDependencies: pino-pretty (used at runtime as a pino transport
  target string in logger.ts, invisible to static analysis).
- ignoreExportsUsedInFile: an export used only inside its own file is a
  redundant modifier / intentional test seam, not dead code; don't churn
  stable shared modules to strip a keyword.
- ignoreBinaries: git subcommands mis-detected from Bun.$ shell templates
  in dev-pipeline/git-ops.ts.

Refs #110
Investigation: GroupSpreadsheet was introduced with the monthly-budget-tabs
feature (6352a74) as the row-shape type for the group_spreadsheets table.
GroupSpreadsheetRepository never adopted it — it reads narrower inline shapes
(SELECT spreadsheet_id ..., {year, spreadsheet_id}) — so the interface has no
importer. It is not orphaned-by-migration (no callsite ever existed:
`git log -S "GroupSpreadsheet("` is empty) but it documents a real table and
mirrors every other row type in this file.

Kept (not deleted) per the conservative dead-code rule; the @public JSDoc tag
exempts it from the knip gate. Wiring it into the repo's return types would
change stable working code and is out of scope.

Refs #110
jsqr was the original QR decoder (added in a447be0, "Implement photo
processing feature"). The QR scanner was migrated to the `qr` package in
25d16da ("feat(qr-scanner): integrate new QR decoding library"), which
removed the jsqr import. Evidence it is now dead:

  git log -S "jsqr"  -> a447be0 (add), 25d16da (remove import)
  grep -rI "jsqr|jsQR" src libs scripts miniapp index.ts bank-sync.ts -> none

No static import, no dynamic import/require anywhere; qr-scanner.ts uses
`qr/decode.js`. Safe to drop.

Refs #110
AgentEvent was the event-union of the original agent streaming design
(added in 0792822, consumed by agent.ts). Commit 5e57a49 migrated the
agent to the AgentStreamWriter push-interface (TelegramStreamWriter),
removing the `import type { ..., AgentEvent, ... } from './types'` line
from agent.ts. Nothing has referenced it since — classic
orphaned-by-migration.

Evidence the last consumer was removed:

  git log -S "AgentEvent" -- src/services/ai/agent.ts
    -> 0792822 (introduce/consume), 5e57a49 (remove import)
  git show 5e57a49 -- src/services/ai/agent.ts
    -> "-import type { AgentContext, AgentEvent, ToolCallResult } from './types'"
  grep -rn AgentEvent src -> only its own definition

ToolResult (referenced by the removed union) stays — still used by
ToolCallResult and elsewhere. Full test suite green.

Refs #110
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

🔁 PR closed. Stage bot switched back to main.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62234efc08

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread knip.jsonc
"bank-sync.ts",
"ecosystem.config.cjs",
"scripts/**/*.ts",
"src/**/*.test.ts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exclude ZenPlugins from test entries

When the ZenPlugins submodule is checked out, this broad test entry still matches files such as src/services/bank/ZenPlugins/src/plugins/tbc-ge/__tests__/api/*.test.ts; Knip analyzes entry roots independently of project, so the project exclusion below does not fully ignore the submodule. In local environments that initialize the submodule, bunx knip can still traverse third-party tests and report their imports/exports; add a !src/services/bank/ZenPlugins/** entry negation or narrow this glob.

Useful? React with 👍 / 👎.

@alex-mextner
alex-mextner merged commit 034a803 into main Jul 1, 2026
12 checks passed
@alex-mextner
alex-mextner deleted the chore/knip-cleanup branch July 1, 2026 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Investigate & resolve knip-flagged unused exports (pre-existing dead-code sweep)

1 participant