Skip to content

chore: add fallow + clean up dead code and duplication#77

Merged
andrelandgraf merged 1 commit into
mainfrom
chore/fallow-cleanup
Apr 30, 2026
Merged

chore: add fallow + clean up dead code and duplication#77
andrelandgraf merged 1 commit into
mainfrom
chore/fallow-cleanup

Conversation

@andrelandgraf
Copy link
Copy Markdown
Collaborator

Summary

Wire up fallow as a dev dependency and document a workflow in AGENTS.md for running npx fallow dead-code and npx fallow dupes after every change, with first-principles guidance on when to remove vs leverage flagged code and when duplication is worth unifying vs leaving alone.

Then ran fallow across the repo and acted only on the findings that genuinely made the codebase clearer.

Dead code removed

  • Delete unused custom components: pillar-strip.tsx, appkit-version-picker.tsx, selected-items.tsx, recipe-list.tsx, copy-button.tsx (verified zero references).
  • Delete dead exports/declarations: getRecipeMarkdownApiPath, COOKBOOK_FILES/CookbookFile, pillars/Pillar, SolutionTag alias, unused useAllRawRecipeMarkdown/useRecipeSections/useRawExampleMarkdown hooks, buildRobotsTxt re-export, dead re-exports in content-markdown.ts.
  • Demote internal-only types to module-private (no behavior change).
  • Drop transitive-only deps date-fns and @hookform/resolvers.
  • Update author-recipes-and-cookbooks skill to match the actual hooks.

Duplication unified (real same-logic-twice cases)

  • New useAgentMarkdown hook consolidates the agent-prompt builder shared by ai-export-menu and copy-prompt-button.
  • New useCookbookMarkdown hook removes ~25 lines of boilerplate from each of the 5 cookbook pages under src/pages/templates/.
  • New BootstrapCopyButton replaces the duplicated copy-state machines in hero-section and wizard-flow (also resolves a CopyPromptButton name collision).
  • Extract buildIncludedTemplateLinks and validateContentFolder helpers for duplicated loops in build-example-markdown.ts and scripts/validate-content.mjs.

Duplication left alone (intentional repetition for clarity)

  • Test files where independent flows happen to share shape.
  • Cross-callsite filter patterns where each consumer reads the catalog differently.
  • Tiny 5-line handler boilerplate where extracting a helper saves nothing.

Configuration

.fallowrc.json scopes future runs by ignoring examples/** and content/**, plus documented false positives (mcp-handler peer dep, Docusaurus type wiring, transitive remark deps, the mcp-handler HTTP method exports, and the shadcn UI kit catalog).

Results

Check Before After
Unused exports (actionable) 33 0
Unused type exports (actionable) 9 0
Unused dependencies (actionable) 3 0
Duplicated lines 5,171 (14.9%) 478 (2.2%)

Net diff: -1,091 lines (-1,396 / +305) across 36 files.

Test plan

  • npm run fmt
  • npm run typecheck
  • npm run validate:content
  • npm run verify:images
  • npm run build
  • npm run test:smoke — 165 tests pass
  • npx fallow dead-code — 0 actionable findings
  • npx fallow dupes — only intentional / accepted patterns remain

Wire up [fallow](https://github.com/fallow-rs/fallow) as a dev dependency and
document a workflow in AGENTS.md for running `npx fallow dead-code` and
`npx fallow dupes` after every change, with first-principles guidance on when
to remove vs leverage flagged code and when duplication is worth unifying vs
leaving alone.

Then ran fallow across the repo and acted only on the findings that genuinely
made the codebase clearer.

Dead code removed:

- Delete unused custom components: `pillar-strip.tsx`, `appkit-version-picker.tsx`,
  `selected-items.tsx`, `recipe-list.tsx`, `copy-button.tsx` (verified zero
  references across the repo)
- Delete dead exports/declarations: `getRecipeMarkdownApiPath`,
  `COOKBOOK_FILES`/`CookbookFile`, `pillars`/`Pillar`, `SolutionTag` alias,
  unused `useAllRawRecipeMarkdown`/`useRecipeSections`/`useRawExampleMarkdown`
  hooks, `buildRobotsTxt` re-export, dead re-exports in `content-markdown.ts`
- Demote internal-only types to module-private (no behavior change)
- Drop transitive-only deps `date-fns` and `@hookform/resolvers`
- Update `author-recipes-and-cookbooks` skill to match the actual hooks

Duplication unified (real same-logic-twice cases):

- New `useAgentMarkdown` hook consolidates the agent-prompt builder shared by
  `ai-export-menu` and `copy-prompt-button`
- New `useCookbookMarkdown` hook removes ~25 lines of boilerplate from each of
  the 5 cookbook pages under `src/pages/templates/`
- New `BootstrapCopyButton` replaces the duplicated copy-state machines in
  `hero-section` and `wizard-flow` (also resolves a `CopyPromptButton`
  name collision)
- Extract `buildIncludedTemplateLinks` and `validateContentFolder` helpers
  for duplicated loops in `build-example-markdown.ts` and
  `scripts/validate-content.mjs`

Duplication left alone (intentional repetition for clarity):

- Test files where independent flows happen to share shape
- Cross-callsite filter patterns where each consumer reads the catalog differently
- Tiny 5-line handler boilerplate where extracting a helper saves nothing

Configuration:

- `.fallowrc.json` scopes future runs by ignoring `examples/**` and
  `content/**`, plus documented false positives (mcp-handler peer dep,
  Docusaurus type wiring, transitive remark deps, the `mcp-handler` HTTP
  method exports, and the shadcn UI kit catalog)

Net: -1,091 lines (-1,396 / +305) across 36 files; duplicated lines drop from
14.9% to 2.2%. `npm run typecheck`, `npm run build`, and 165 smoke tests pass.
@andrelandgraf
Copy link
Copy Markdown
Collaborator Author

Thanks @thisistonydang for tweeting about fallow ;)

@andrelandgraf andrelandgraf merged commit 9e7a254 into main Apr 30, 2026
@andrelandgraf andrelandgraf deleted the chore/fallow-cleanup branch April 30, 2026 16:09
andrelandgraf added a commit that referenced this pull request May 1, 2026
The fallow package was added to devDependencies in #77 while npm was
configured to use the internal Databricks npm proxy, which baked
`https://npm-proxy.dev.databricks.com/...` URLs into 8 lockfile entries
(fallow + its 7 platform-specific binaries). Vercel's build server
cannot reach that internal proxy, so production deploys fail with
ETIMEDOUT during `npm install`.

Rewrites the 8 affected `resolved` URLs to `https://registry.npmjs.org/`.
Integrity hashes are content-based and unchanged, so installs still
verify against the public registry's tarballs.
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.

1 participant