Skip to content

Release/2.0.20#2206

Merged
mikib0 merged 121 commits intomainfrom
release/2.0.20
Apr 16, 2026
Merged

Release/2.0.20#2206
mikib0 merged 121 commits intomainfrom
release/2.0.20

Conversation

@mikib0
Copy link
Copy Markdown
Collaborator

@mikib0 mikib0 commented Apr 16, 2026

This pull request introduces several improvements across environment variable management, dependency updates, and API robustness. The most significant changes include a refactor of how public environment variables are handled for different client apps, updates to core dependencies, and enhanced error handling in API routes. Below are the most important changes grouped by theme:

Environment Variable Management:

  • Refactored the handling of public environment variables: variables prefixed with PUBLIC_ in .env.example are now automatically mapped to EXPO_PUBLIC_ for Expo apps and NEXT_PUBLIC_ for Next.js apps via .github/scripts/env.ts, ensuring a single source of truth and reducing duplication. (.env.example, .github/scripts/env.ts) [1] [2]
  • Updated all usages in the admin app to require NEXT_PUBLIC_API_URL (derived from PUBLIC_API_URL) and throw explicit errors if not set, improving configuration safety. (apps/admin/app/login/page.tsx, apps/admin/lib/api.ts) [1] [2]

Dependency and Version Updates:

  • Bumped version numbers across all apps and packages from 2.0.19 to 2.0.20 and updated several dependencies (notably Drizzle ORM, Vitest, and development tools) to their latest compatible versions for improved stability and security. (package.json, apps/*/package.json, packages/*/package.json) [1] [2] [3] [4] [5] [6]
  • Removed the unused recharts dependency from all relevant frontend apps. (apps/admin/package.json, apps/guides/package.json, apps/landing/package.json) [1] [2] [3]

API and Error Handling Improvements:

  • Improved catalog item API routes by introducing a robust parseIntegerId utility to validate and parse item IDs, returning a 404 error for invalid IDs instead of relying on Number(). (packages/api/src/routes/catalog/deleteCatalogItemRoute.ts, packages/api/src/routes/catalog/getCatalogItemRoute.ts, packages/api/src/routes/catalog/getSimilarCatalogItemsRoute.ts) [1] [2] [3] [4] [5] [6]
  • Enhanced error handling in the admin API routes, including more accurate detection of database constraint errors and explicit JWT algorithm specification. (packages/api/src/routes/admin/index.ts) [1] [2]

Other Notable Changes:

  • Updated Cloudflare Wrangler config for the admin app to set the correct compatibility date and SPA handling. (apps/admin/wrangler.jsonc)
  • Added new scripts for the MCP package and improved test/dev workflow commands in the monorepo. (package.json)
  • Added and updated polyfills and dependencies for better React Native compatibility. (apps/expo/package.json, apps/expo/polyfills.js) [1] [2] [3]

Summary by CodeRabbit

  • New Features

    • Added MCP server with tools for packs, catalog, trips, weather, knowledge, and trail conditions
    • Unified PUBLIC_ client env var convention for multi-target apps
  • Improvements

    • Stricter numeric ID validation and clearer 404 behavior for invalid route params
    • Require API URL env in admin UI; improved SPA routing behavior on edge
  • Tests

    • Substantially expanded unit and integration tests across API and MCP
  • Chores

    • Version bumps to 2.0.20, dependency updates, removed unused charting library, updated gitignore and dev env examples

claude and others added 30 commits April 14, 2026 12:32
Introduces packages/mcp: a complete Model Context Protocol server built
on Cloudflare Agents SDK (McpAgent / Durable Objects) that exposes
PackRat's core functionality to any MCP-compatible AI client.

Features:
- 20 tools across 5 domains: packs, gear catalog, trips, weather, knowledge
- 4 guided prompts: plan_trip, optimize_pack_weight, recommend_gear, trail_research
- 4 MCP resources: pack, trip, catalog_item, gear_categories (URI templates)
- JWT Bearer token auth — token captured from each request, stored in DO state
- Streamable HTTP transport (default) + SSE via McpAgent.serve()
- Hibernation support via SQLite-backed Durable Objects

Key tools:
  Packs: list, get, create, update, delete, add/remove items, AI generate, weight analysis, gap analysis
  Catalog: text search, semantic vector search, get item, list categories, compare items
  Trips: list, get, create, update, delete
  Weather: current conditions + forecast, season suggestions
  Knowledge: outdoor guides RAG, Perplexity web search, read-only SQL, DB schema
  Trails: get conditions, submit condition report

Connection: https://<worker>.workers.dev/mcp
Auth: Authorization: Bearer <packrat-jwt>

https://claude.ai/code/session_01UPTmzL2JtXyTZSpbyqE9j5
Bumps [@ai-sdk/perplexity](https://github.com/vercel/ai) from 2.0.27 to 3.0.29.
- [Release notes](https://github.com/vercel/ai/releases)
- [Changelog](https://github.com/vercel/ai/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vercel/ai/compare/@ai-sdk/perplexity@2.0.27...@ai-sdk/perplexity@3.0.29)

---
updated-dependencies:
- dependency-name: "@ai-sdk/perplexity"
  dependency-version: 3.0.29
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 3.1.4 to 4.1.4.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.4/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.1.4
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@scalar/hono-api-reference](https://github.com/scalar/scalar/tree/HEAD/integrations/hono) from 0.8.10 to 0.10.7.
- [Release notes](https://github.com/scalar/scalar/releases)
- [Changelog](https://github.com/scalar/scalar/blob/main/integrations/hono/CHANGELOG.md)
- [Commits](https://github.com/scalar/scalar/commits/HEAD/integrations/hono)

---
updated-dependencies:
- dependency-name: "@scalar/hono-api-reference"
  dependency-version: 0.10.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [drizzle-kit](https://github.com/drizzle-team/drizzle-orm) from 0.30.6 to 0.31.10.
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](https://github.com/drizzle-team/drizzle-orm/compare/drizzle-kit@0.30.6...drizzle-kit@0.31.10)

---
updated-dependencies:
- dependency-name: drizzle-kit
  dependency-version: 0.31.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@ai-sdk/google](https://github.com/vercel/ai) from 2.0.67 to 3.0.62.
- [Release notes](https://github.com/vercel/ai/releases)
- [Changelog](https://github.com/vercel/ai/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vercel/ai/compare/@ai-sdk/google@2.0.67...@ai-sdk/google@3.0.62)

---
updated-dependencies:
- dependency-name: "@ai-sdk/google"
  dependency-version: 3.0.62
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) from 2.1.9 to 4.10.0.
- [Release notes](https://github.com/bvaughn/react-resizable-panels/releases)
- [Changelog](https://github.com/bvaughn/react-resizable-panels/blob/main/CHANGELOG.md)
- [Commits](bvaughn/react-resizable-panels@2.1.9...4.10.0)

---
updated-dependencies:
- dependency-name: react-resizable-panels
  dependency-version: 4.10.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [cmdk](https://github.com/pacocoursey/cmdk/tree/HEAD/cmdk) from 1.0.4 to 1.1.1.
- [Release notes](https://github.com/pacocoursey/cmdk/releases)
- [Commits](https://github.com/pacocoursey/cmdk/commits/v1.1.1/cmdk)

---
updated-dependencies:
- dependency-name: cmdk
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [recharts](https://github.com/recharts/recharts) from 2.15.0 to 3.8.1.
- [Release notes](https://github.com/recharts/recharts/releases)
- [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md)
- [Commits](recharts/recharts@v2.15.0...v3.8.1)

---
updated-dependencies:
- dependency-name: recharts
  dependency-version: 3.8.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.454.0 to 1.8.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.8.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [react-day-picker](https://github.com/gpbl/react-day-picker) from 8.10.1 to 9.14.0.
- [Release notes](https://github.com/gpbl/react-day-picker/releases)
- [Changelog](https://github.com/gpbl/react-day-picker/blob/main/CHANGELOG.md)
- [Commits](gpbl/react-day-picker@v8.10.1...v9.14.0)

---
updated-dependencies:
- dependency-name: react-day-picker
  dependency-version: 9.14.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [postcss-import](https://github.com/postcss/postcss-import) from 15.1.0 to 16.1.1.
- [Release notes](https://github.com/postcss/postcss-import/releases)
- [Changelog](https://github.com/postcss/postcss-import/blob/master/CHANGELOG.md)
- [Commits](postcss/postcss-import@15.1.0...16.1.1)

---
updated-dependencies:
- dependency-name: postcss-import
  dependency-version: 16.1.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [sonner](https://github.com/emilkowalski/sonner) from 1.7.4 to 2.0.7.
- [Release notes](https://github.com/emilkowalski/sonner/releases)
- [Commits](https://github.com/emilkowalski/sonner/commits/v2.0.7)

---
updated-dependencies:
- dependency-name: sonner
  dependency-version: 2.0.7
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [cmdk](https://github.com/pacocoursey/cmdk/tree/HEAD/cmdk) from 1.0.4 to 1.1.1.
- [Release notes](https://github.com/pacocoursey/cmdk/releases)
- [Commits](https://github.com/pacocoursey/cmdk/commits/v1.1.1/cmdk)

---
updated-dependencies:
- dependency-name: cmdk
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.0.14 to 19.2.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.14
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [sonner](https://github.com/emilkowalski/sonner) from 1.7.4 to 2.0.7.
- [Release notes](https://github.com/emilkowalski/sonner/releases)
- [Commits](https://github.com/emilkowalski/sonner/commits/v2.0.7)

---
updated-dependencies:
- dependency-name: sonner
  dependency-version: 2.0.7
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [eslint-config-universe](https://github.com/expo/expo/tree/HEAD/packages/eslint-config-universe) from 12.1.0 to 15.0.3.
- [Changelog](https://github.com/expo/expo/blob/main/packages/eslint-config-universe/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/eslint-config-universe)

---
updated-dependencies:
- dependency-name: eslint-config-universe
  dependency-version: 15.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [react-native-maps](https://github.com/react-native-maps/react-native-maps) from 1.20.1 to 1.27.2.
- [Release notes](https://github.com/react-native-maps/react-native-maps/releases)
- [Changelog](https://github.com/react-native-maps/react-native-maps/blob/master/CHANGELOG.md)
- [Commits](react-native-maps/react-native-maps@v1.20.1...v1.27.2)

---
updated-dependencies:
- dependency-name: react-native-maps
  dependency-version: 1.27.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 3.1.4 to 4.1.4.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.4/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-version: 4.1.4
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the drizzle group with 2 updates: [drizzle-kit](https://github.com/drizzle-team/drizzle-orm) and [drizzle-orm](https://github.com/drizzle-team/drizzle-orm).


Updates `drizzle-kit` from 0.30.6 to 0.31.10
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](https://github.com/drizzle-team/drizzle-orm/compare/drizzle-kit@0.30.6...drizzle-kit@0.31.10)

Updates `drizzle-orm` from 0.44.7 to 0.45.2
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](drizzle-team/drizzle-orm@0.44.7...0.45.2)

---
updated-dependencies:
- dependency-name: drizzle-kit
  dependency-version: 0.31.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: drizzle
- dependency-name: drizzle-orm
  dependency-version: 0.45.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: drizzle
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the expo-sdk group with 22 updates:

| Package | From | To |
| --- | --- | --- |
| [expo-apple-authentication](https://github.com/expo/expo/tree/HEAD/packages/expo-apple-authentication) | `8.0.8` | `55.0.13` |
| [expo-blur](https://github.com/expo/expo/tree/HEAD/packages/expo-blur) | `15.0.8` | `55.0.14` |
| [expo-clipboard](https://github.com/expo/expo/tree/HEAD/packages/expo-clipboard) | `8.0.8` | `55.0.13` |
| [expo-constants](https://github.com/expo/expo/tree/HEAD/packages/expo-constants) | `18.0.13` | `55.0.13` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client) | `6.0.20` | `55.0.27` |
| [expo-file-system](https://github.com/expo/expo/tree/HEAD/packages/expo-file-system) | `19.0.21` | `55.0.16` |
| [expo-haptics](https://github.com/expo/expo/tree/HEAD/packages/expo-haptics) | `15.0.8` | `55.0.14` |
| [expo-image](https://github.com/expo/expo/tree/HEAD/packages/expo-image) | `3.0.11` | `55.0.8` |
| [expo-image-picker](https://github.com/expo/expo/tree/HEAD/packages/expo-image-picker) | `17.0.10` | `55.0.18` |
| [expo-linear-gradient](https://github.com/expo/expo/tree/HEAD/packages/expo-linear-gradient) | `15.0.8` | `55.0.13` |
| [expo-linking](https://github.com/expo/expo/tree/HEAD/packages/expo-linking) | `8.0.11` | `55.0.12` |
| [expo-localization](https://github.com/expo/expo/tree/HEAD/packages/expo-localization) | `17.0.8` | `55.0.13` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location) | `19.0.8` | `55.1.8` |
| [expo-navigation-bar](https://github.com/expo/expo/tree/HEAD/packages/expo-navigation-bar) | `5.0.10` | `55.0.12` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router) | `6.0.23` | `55.0.12` |
| [expo-secure-store](https://github.com/expo/expo/tree/HEAD/packages/expo-secure-store) | `15.0.8` | `55.0.13` |
| [expo-sqlite](https://github.com/expo/expo/tree/HEAD/packages/expo-sqlite) | `16.0.10` | `55.0.15` |
| [expo-status-bar](https://github.com/expo/expo/tree/HEAD/packages/expo-status-bar) | `3.0.9` | `55.0.5` |
| [expo-store-review](https://github.com/expo/expo/tree/HEAD/packages/expo-store-review) | `9.0.9` | `55.0.13` |
| [expo-system-ui](https://github.com/expo/expo/tree/HEAD/packages/expo-system-ui) | `6.0.9` | `55.0.15` |
| [expo-updates](https://github.com/expo/expo/tree/HEAD/packages/expo-updates) | `29.0.16` | `55.0.20` |
| [expo-web-browser](https://github.com/expo/expo/tree/HEAD/packages/expo-web-browser) | `15.0.10` | `55.0.14` |


Updates `expo-apple-authentication` from 8.0.8 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-apple-authentication/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-apple-authentication)

Updates `expo-blur` from 15.0.8 to 55.0.14
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-blur/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-blur)

Updates `expo-clipboard` from 8.0.8 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-clipboard/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-clipboard)

Updates `expo-constants` from 18.0.13 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-constants)

Updates `expo-dev-client` from 6.0.20 to 55.0.27
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-dev-client/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-client)

Updates `expo-file-system` from 19.0.21 to 55.0.16
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-file-system)

Updates `expo-haptics` from 15.0.8 to 55.0.14
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-haptics/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-haptics)

Updates `expo-image` from 3.0.11 to 55.0.8
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-image/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-image)

Updates `expo-image-picker` from 17.0.10 to 55.0.18
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-image-picker)

Updates `expo-linear-gradient` from 15.0.8 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-linear-gradient/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-linear-gradient)

Updates `expo-linking` from 8.0.11 to 55.0.12
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-linking)

Updates `expo-localization` from 17.0.8 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-localization/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-localization)

Updates `expo-location` from 19.0.8 to 55.1.8
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-location/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-location)

Updates `expo-navigation-bar` from 5.0.10 to 55.0.12
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-navigation-bar/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-navigation-bar)

Updates `expo-router` from 6.0.23 to 55.0.12
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-router)

Updates `expo-secure-store` from 15.0.8 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-secure-store/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-secure-store)

Updates `expo-sqlite` from 16.0.10 to 55.0.15
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-sqlite/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-sqlite)

Updates `expo-status-bar` from 3.0.9 to 55.0.5
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-status-bar/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-status-bar)

Updates `expo-store-review` from 9.0.9 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-store-review/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-store-review)

Updates `expo-system-ui` from 6.0.9 to 55.0.15
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-system-ui/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-system-ui)

Updates `expo-updates` from 29.0.16 to 55.0.20
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-updates)

Updates `expo-web-browser` from 15.0.10 to 55.0.14
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-web-browser/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-web-browser)

---
updated-dependencies:
- dependency-name: expo-apple-authentication
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-blur
  dependency-version: 55.0.14
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-clipboard
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-constants
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-dev-client
  dependency-version: 55.0.27
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-file-system
  dependency-version: 55.0.16
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-haptics
  dependency-version: 55.0.14
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-image
  dependency-version: 55.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-image-picker
  dependency-version: 55.0.18
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-linear-gradient
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-linking
  dependency-version: 55.0.12
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-localization
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-location
  dependency-version: 55.1.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-navigation-bar
  dependency-version: 55.0.12
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-router
  dependency-version: 55.0.12
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-secure-store
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-sqlite
  dependency-version: 55.0.15
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-status-bar
  dependency-version: 55.0.5
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-store-review
  dependency-version: 55.0.13
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-system-ui
  dependency-version: 55.0.15
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-updates
  dependency-version: 55.0.20
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
- dependency-name: expo-web-browser
  dependency-version: 55.0.14
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: expo-sdk
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [eslint](https://github.com/eslint/eslint) from 8.57.1 to 10.2.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v8.57.1...v10.2.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 10.2.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@sentry/react-native](https://github.com/getsentry/sentry-react-native) from 7.2.0 to 8.7.0.
- [Release notes](https://github.com/getsentry/sentry-react-native/releases)
- [Changelog](https://github.com/getsentry/sentry-react-native/blob/main/CHANGELOG.md)
- [Commits](getsentry/sentry-react-native@7.2.0...8.7.0)

---
updated-dependencies:
- dependency-name: "@sentry/react-native"
  dependency-version: 8.7.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) from 3.1.4 to 4.1.4.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.4/packages/coverage-v8)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.1.4
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [eslint-config-universe](https://github.com/expo/expo/tree/HEAD/packages/eslint-config-universe) from 12.1.0 to 15.0.3.
- [Changelog](https://github.com/expo/expo/blob/main/packages/eslint-config-universe/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/eslint-config-universe)

---
updated-dependencies:
- dependency-name: eslint-config-universe
  dependency-version: 15.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

cloudflare-workers-and-pages Bot commented Apr 16, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
packrat-admin 8375d56 Commit Preview URL

Branch Preview URL
Apr 16 2026, 11:58 AM

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file api ci/cd mobile web labels Apr 16, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4977e0c6-c13a-40b4-8c38-427b7b9757b9

📥 Commits

Reviewing files that changed from the base of the PR and between 97288e1 and 8375d56.

📒 Files selected for processing (2)
  • packages/api/test/packs.test.ts
  • packages/web-ui/src/components/calendar.tsx

📝 Walkthrough

Walkthrough

Adds a new MCP package (worker + Durable Object + tools + tests), standardizes client env vars to PUBLIC_* with fan-out to app-specific prefixes, tightens integer ID parsing across API routes, updates many package versions/dependencies, adjusts tests and test setup, and removes/relocates some recharts usages.

Changes

Cohort / File(s) Summary
Env & Fan-out scripts
\.env\.example, .github/scripts/env.ts, \.gitignore
Renamed client-exposed vars to PUBLIC_*; env fan-out script now writes NEXT_PUBLIC_* for Next apps; added .dev.vars to .gitignore.
Admin app
apps/admin/... (app/login/page.tsx, lib/api.ts, package.json, wrangler.jsonc)
Require NEXT_PUBLIC_API_URL at runtime (throw on missing); bumped version; removed recharts; updated wrangler compatibility date and SPA routing.
Expo app
apps/expo/... (app.config.ts, components/Icon/Icon.ios.tsx, package.json, polyfills.js)
Version bump; added react-native-blob-util and react-native-get-random-values; unconditional random-values polyfill import; minor type assertion removal.
Landing & Guides apps
apps/landing/package.json, apps/guides/package.json
Version bumps; removed recharts dependency.
API code & routes
packages/api/src/..., packages/api/package.json, packages/api/wrangler.jsonc
Added routeParams integer ID schema + parseIntegerId and applied to catalog/chat routes; explicit HS256 on JWT verify; drizzle/vitest bumps; added Durable Objects migration v3 to delete TikTokContainer.
API tests & test infra
packages/api/test/*, packages/api/test/setup.ts, tests/utils/db-helpers.ts, packages/api/vitest.config.ts
Major test refactor: add seedAndLoginTestUser, change seeding to seed+login, broaden global mocks (ai, catalogService, container fetch), DB truncation via testDb, single-worker tests, and many expanded/added tests.
New MCP package
packages/mcp/* (src/index.ts, client.ts, tools/*, resources.ts, prompts.ts, types.ts, tests, wrangler, tsconfig, package.json`, etc.)
New Model Context Protocol worker: PackRatMCP Durable Object, PackRatApiClient, tool registrations (catalog/packs/trips/weather/knowledge/trail-conditions), resources, prompts, types, tests, wrangler config with Durable Object migrations and SQLite, and package tooling.
Web UI changes
packages/web-ui/* (package.json, src/components/calendar.tsx, chart.tsx, resizable.tsx)
Added recharts to web-ui; unified Chevron for calendar nav; refactored chart tooltip/legend typing and rendering logic; updated resizable API for v4.
Monorepo metadata & config
package.json, tsconfig.json, various package.json bumps (packages/*)
Version bumps from 2.0.19 → 2.0.20 across many packages; added MCP scripts in root package.json; excluded packages/mcp from root tsconfig.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Worker as "Worker (/fetch)"
  participant DO as "PackRatMCP (Durable Object)"
  participant API as "PackRat API"
  Client->>Worker: Request /mcp (Authorization: Bearer <token>)
  Worker->>DO: forward request
  Note right of DO: Extract Bearer token\npersist to DO state (authToken)
  DO->>DO: init() registers tools/resources/prompts
  DO->>API: PackRatApiClient.get/post/... (attach Bearer from state)
  API-->>DO: Response (data or error)
  DO-->>Worker: response
  Worker-->>Client: proxied response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~65 minutes

Possibly related PRs

Suggested labels

database

Suggested reviewers

  • andrew-bierman
  • Isthisanmol

"I’m a rabbit in the code-fed glade,
Tools and prompts and tests I made.
Env vars tidy, MCP now springs,
Hops of joy for versioned things—
A tiny drumroll for new package strings!" 🐇✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Release/2.0.20' is generic and vague, using a standard release naming convention without conveying meaningful details about the actual changeset. Consider a more descriptive title that summarizes the primary changes, e.g., 'Release 2.0.20: Add MCP server, unify env vars, improve API validation, and upgrade dependencies' or similar.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/2.0.20

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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 16, 2026

Coverage Report for API Unit Tests Coverage (./packages/api)

Status Category Percentage Covered / Total
🔵 Lines 85.86% 905 / 1054
🔵 Statements 85.86% (🎯 80%) 905 / 1054
🔵 Functions 94.11% 48 / 51
🔵 Branches 89.2% 281 / 315
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/api/src/utils/routeParams.ts 0% 0% 0% 0% 1-24
Generated in workflow #503 for commit 8375d56 by the Vitest Coverage Report Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 16, 2026

Coverage Report for Expo Unit Tests Coverage (./apps/expo)

Status Category Percentage Covered / Total
🔵 Lines 80.15% 517 / 645
🔵 Statements 80.15% (🎯 75%) 517 / 645
🔵 Functions 92.85% 52 / 56
🔵 Branches 92.55% 199 / 215
File CoverageNo changed files found.
Generated in workflow #503 for commit 8375d56 by the Vitest Coverage Report Action

@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

cloudflare-workers-and-pages Bot commented Apr 16, 2026

Deploying packrat-guides with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8375d56
Status:⚡️  Build in progress...

View logs

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Release 2.0.20 focusing on consolidating client-exposed env var handling across Expo/Next.js, adding a new MCP server package, and improving API robustness + test stability (notably around route param parsing and Workers test isolation).

Changes:

  • Refactored env var generation so PUBLIC_* in root .env.local fans out to EXPO_PUBLIC_* (Expo) and NEXT_PUBLIC_* (Next.js) automatically.
  • Added @packrat/mcp Cloudflare Worker/Durable Object MCP server with tools/resources/prompts plus a Vitest unit test suite.
  • Hardened API route param parsing via parseIntegerId, improved admin auth/error handling, and stabilized API test execution/fixtures.

Reviewed changes

Copilot reviewed 68 out of 71 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tsconfig.json Excludes new packages/mcp from root TS compilation scope.
packages/web-ui/src/components/resizable.tsx Updates react-resizable-panels v4 component names.
packages/web-ui/src/components/chart.tsx Migrates assert helper import, adjusts tooltip/legend typing for recharts v3.
packages/web-ui/src/components/calendar.tsx Updates react-day-picker v9 chevron component API usage.
packages/web-ui/package.json Bumps version, adds @packrat/guards, adds recharts dependency.
packages/ui/package.json Version bump to 2.0.20.
packages/mcp/wrangler.jsonc Adds Wrangler config for MCP Worker + Durable Object bindings/migrations.
packages/mcp/vitest.config.ts Adds MCP unit test + coverage configuration.
packages/mcp/tsconfig.json Adds MCP package TS config for Workers build.
packages/mcp/src/types.ts Introduces AgentContext to avoid circular imports for registrations.
packages/mcp/src/tools/weather.ts Implements weather-related MCP tools (search + forecast + season suggestions).
packages/mcp/src/tools/trips.ts Implements trip CRUD MCP tools.
packages/mcp/src/tools/trail-conditions.ts Implements trail conditions list/submit MCP tools.
packages/mcp/src/tools/packs.ts Implements packs CRUD + analysis MCP tools.
packages/mcp/src/tools/knowledge.ts Implements RAG/web/sql/schema MCP tools.
packages/mcp/src/tools/catalog.ts Implements catalog search/get/compare MCP tools.
packages/mcp/src/resources.ts Adds MCP resources (pack/trip/catalog/categories) via URI templates.
packages/mcp/src/prompts.ts Adds guided prompts (trip planning, optimization, recommendations, research).
packages/mcp/src/index.ts Adds Worker entrypoint + auth guard + Durable Object agent implementation.
packages/mcp/src/client.ts Adds authenticated PackRat API client + ok/err helpers for tool results.
packages/mcp/src/tests/tools/weather.test.ts Unit tests for weather tools registration and behaviors.
packages/mcp/src/tests/tools/trips.test.ts Unit tests for trip tools registration and behaviors.
packages/mcp/src/tests/tools/trail-conditions.test.ts Unit tests for trail condition tools registration and behaviors.
packages/mcp/src/tests/tools/packs.test.ts Unit tests for pack tools registration and behaviors.
packages/mcp/src/tests/tools/knowledge.test.ts Unit tests for knowledge tools registration and behaviors.
packages/mcp/src/tests/tools/catalog.test.ts Unit tests for catalog tools registration and behaviors.
packages/mcp/src/tests/helpers.ts Shared MCP test harness for capturing registered tools/resources/prompts.
packages/mcp/src/tests/client.test.ts Unit tests for the MCP API client and ok/err formatting helpers.
packages/mcp/src/tests/auth.test.ts Unit tests for Worker auth guard + routing without real DO spin-up.
packages/mcp/package.json Adds MCP package metadata, deps, scripts (dev/deploy/test).
packages/mcp/.dev.vars.example Provides local Wrangler vars example for MCP package.
packages/guards/package.json Version bump to 2.0.20.
packages/cli/package.json Version bump to 2.0.20.
packages/api/wrangler.jsonc Adds migration to delete stale DO class (TikTokContainer).
packages/api/vitest.config.ts Uses singleWorker: true to avoid DB deadlocks from per-file isolate teardown.
packages/api/test/utils/db-helpers.ts Splits seedTestUser vs seedAndLoginTestUser for clearer auth setup.
packages/api/test/upload.test.ts Uses seedAndLoginTestUser and avoids hard-coded user IDs in fileName.
packages/api/test/setup.ts Improves global mocking and makes DB cleanup consistent via testDb.execute.
packages/api/test/packs.test.ts Updates mocking + auth flows; uses apiWithAuthAs for cross-user checks.
packages/api/test/pack-templates.test.ts Uses seedAndLoginTestUser to ensure apiWithAuth has a real DB user.
packages/api/test/image-detection.test.ts Uses seedAndLoginTestUser for auth consistency.
packages/api/test/generate-from-online-content.test.ts Moves container/AI/catalog mocks to global setup patterns; adds per-test override hook.
packages/api/test/chat.test.ts Updates assertions for SSE streaming contract rather than JSON response body.
packages/api/test/catalog.test.ts Adds stronger assertions for invalid catalog IDs returning 404 consistently.
packages/api/test/auth.test.ts Adds coverage for verify-email, reset-password, and refresh token behaviors.
packages/api/test/admin.test.ts Adds coverage for admin delete/stats/conflict paths with FK-restricted data.
packages/api/src/utils/routeParams.ts Adds parseIntegerId + schema to validate int4 IDs and prevent coercion edge cases.
packages/api/src/routes/chat.ts Uses parseIntegerId for report ID parsing and clean 404s.
packages/api/src/routes/catalog/updateCatalogItemRoute.ts Uses parseIntegerId for catalog item ID parsing and clean 404s.
packages/api/src/routes/catalog/getSimilarCatalogItemsRoute.ts Uses parseIntegerId for catalog item ID parsing and clean 404s.
packages/api/src/routes/catalog/getCatalogItemRoute.ts Uses parseIntegerId for catalog item ID parsing and clean 404s.
packages/api/src/routes/catalog/deleteCatalogItemRoute.ts Uses parseIntegerId for catalog item ID parsing and clean 404s.
packages/api/src/routes/admin/index.ts Specifies JWT algorithm for verify; improves FK constraint error detection (23503).
packages/api/package.json Bumps Drizzle/Vitest versions and repo version alignment.
packages/api/container_src/package.json Version bump to 2.0.20.
packages/analytics/package.json Version bump + Vitest patch bump.
package.json Version bump + adds MCP dev/deploy/test scripts.
apps/landing/package.json Version bump; removes unused recharts dependency.
apps/guides/package.json Version bump; removes unused recharts dependency.
apps/expo/polyfills.js Adds react-native-get-random-values polyfill import.
apps/expo/package.json Version bump; adds RN deps and bumps Vitest tooling.
apps/expo/components/Icon/Icon.ios.tsx Simplifies SymbolView name typing/cast.
apps/expo/app.config.ts App version bump to 2.0.20.
apps/admin/wrangler.jsonc Updates compatibility date and SPA asset handling.
apps/admin/package.json Version bump; removes unused recharts dependency.
apps/admin/lib/api.ts Requires NEXT_PUBLIC_API_URL explicitly (no localhost fallback).
apps/admin/app/login/page.tsx Requires NEXT_PUBLIC_API_URL explicitly (no localhost fallback).
.gitignore Ignores .dev.vars files.
.github/scripts/env.ts Adds Next.js .env.local generation mapping PUBLIC_NEXT_PUBLIC_.
.env.example Consolidates client env vars under PUBLIC_ and documents fan-out behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/web-ui/src/components/calendar.tsx Outdated
Comment thread packages/api/test/packs.test.ts Outdated
Comment thread packages/api/test/packs.test.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/api/test/utils/db-helpers.ts (1)

39-61: ⚠️ Potential issue | 🟡 Minor

Update outdated comments in test-helpers.ts that claim seedTestUser sets currentTestUser.

The comments at lines 18 and 57 state that seedTestUser sets the JWT subject for tests, but the current implementation no longer does this. All existing test callers either use explicit credentials (apiWithAuthAs) or basic auth (apiWithBasicAuth), so the behavioral change is safe in practice. However, the stale comments are misleading and should be updated to reflect that tests requiring both a seeded user and auth context must now call seedAndLoginTestUser() or explicitly set JWT credentials.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/api/test/utils/db-helpers.ts` around lines 39 - 61, Update the
outdated comment above seedTestUser to remove the claim that it sets the JWT
subject/currentTestUser and instead state that seedTestUser only creates a user
in the DB and does NOT authenticate; mention that tests which need an
authenticated context should call seedAndLoginTestUser() or use
apiWithAuthAs/apiWithBasicAuth/loginAs to set JWT/basic auth credentials. Refer
to seedTestUser, seedAndLoginTestUser, loginAs, apiWithAuthAs, and
apiWithBasicAuth in the updated comment so callers know the correct helpers to
use.
packages/api/src/routes/chat.ts (1)

362-379: ⚠️ Potential issue | 🟠 Major

PATCH /reports/{id} still returns 200 for non-existent IDs.

You correctly reject malformed IDs, but a valid integer ID with no matching row still returns { success: true } (Line 378).
This contradicts the route’s documented 404 Report not found response and can mislead admin tooling.

Suggested fix
   const id = parseIntegerId(c.req.param('id'));
   if (id === null) {
     return c.json({ error: 'Report not found' }, 404);
   }
   const { status } = await c.req.json();

+  const existing = await db.query.reportedContent.findFirst({
+    where: eq(reportedContent.id, id),
+    columns: { id: true },
+  });
+  if (!existing) {
+    return c.json({ error: 'Report not found' }, 404);
+  }
+
   await db
     .update(reportedContent)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/api/src/routes/chat.ts` around lines 362 - 379, The handler accepts
a valid integer ID but always returns { success: true } even when no row is
updated; change the code that runs
db.update(reportedContent).set(...).where(eq(reportedContent.id, id)) to capture
the update result and check whether any rows were affected (e.g., inspect the
returned row count/affectedRows from the update call). If zero rows were
updated, return c.json({ error: 'Report not found' }, 404); otherwise continue
to return the success response. Ensure you perform this check immediately after
the update and before the final return.
🧹 Nitpick comments (6)
packages/api/package.json (1)

61-61: Remove drizzle-orm from devDependencies.

drizzle-orm is already declared in dependencies (line 36) with the same version. Remove the duplicate from devDependencies (line 61) to reduce manifest noise.

Suggested patch
   "devDependencies": {
     "@cloudflare/vitest-pool-workers": "0.8.71",
     "@cloudflare/workers-types": "^4.20250405.0",
     "@types/bun": "latest",
     "@types/pg": "^8.11.15",
     "@types/ws": "^8.5.14",
     "@vitest/coverage-v8": "~3.1.4",
     "concurrently": "^8.2.2",
-    "drizzle-orm": "^0.45.2",
     "typed-htmx": "^0.3.1",
     "vitest": "~3.1.4",
     "wrangler": "^4.21.2"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/api/package.json` at line 61, Remove the duplicate devDependency
entry for "drizzle-orm" in package.json (the devDependencies entry where
"drizzle-orm": "^0.45.2" is listed); since "drizzle-orm" is already declared
under dependencies (same version), delete the devDependencies key/value pair to
avoid duplication and keep a single source of truth for the package.
packages/web-ui/src/components/resizable.tsx (1)

8-15: Add backwards compatibility for the direction prop.

react-resizable-panels v4 (currently v4.10.0) renamed direction to orientation. While this wrapper currently has no internal call sites, it exposes Group props directly via ...props, creating a potential breaking change for external consumers. Add a compatibility shim to accept the old prop name:

Compatibility shim
+type ResizablePanelGroupProps = Omit<
+  React.ComponentProps<typeof ResizablePrimitive.Group>,
+  'orientation'
+> & {
+  direction?: React.ComponentProps<typeof ResizablePrimitive.Group>['orientation'];
+};
+
 const ResizablePanelGroup = ({
   className,
-  ...props
-}: React.ComponentProps<typeof ResizablePrimitive.Group>) => (
+  direction,
+  orientation,
+  ...props
+}: ResizablePanelGroupProps) => (
   <ResizablePrimitive.Group
+    orientation={orientation ?? direction}
     className={cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className)}
     {...props}
   />
 );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/web-ui/src/components/resizable.tsx` around lines 8 - 15, The
wrapper ResizablePanelGroup should accept the legacy prop name "direction" and
forward it as "orientation" to ResizablePrimitive.Group to avoid breaking
external consumers; update the component to destructure props (e.g., const {
direction, orientation, ...rest } = props), compute const finalOrientation =
orientation ?? direction, and pass orientation={finalOrientation} along with
{...rest} into ResizablePrimitive.Group (preferring orientation when both
present) so external callers using the old prop continue to work.
packages/api/test/auth.test.ts (1)

199-219: Verify the persisted email-verification state as well.

This test only checks the response payload. If the handler returns success: true but never marks the user as verified, the test still passes. Add a DB assertion or a follow-up login assertion that depends on emailVerified being updated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/api/test/auth.test.ts` around lines 199 - 219, Add a DB-level
assertion after the verify-email request to ensure the user's emailVerified flag
was persisted: after calling authApi('/verify-email', ...) and asserting
response success, query the test database using the existing createDb instance
(e.g., db.select(...).from(users) or appropriate query helper) to fetch the user
by user.id (created via createTestUser) and assert that the returned record has
emailVerified === true; this ensures the handler not only returns success but
also updates the users table accordingly.
packages/api/test/admin.test.ts (1)

131-137: Assert the soft-delete side effect, not just the 200.

This still passes if the handler hard-deletes the pack or no-ops. Read the row back and assert the soft-delete marker changed so the test actually protects the contract it names.

Based on learnings, Implement soft deletes for all user content in the API database.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/api/test/admin.test.ts` around lines 131 - 137, The test only
asserts a 200 response for DELETE but doesn't verify the soft-delete side
effect; update the test that uses seedTestUser, seedPack and apiWithBasicAuth to
read the pack back from the database (via the Pack model/repository used in
tests) after the DELETE and assert the soft-delete marker (e.g., deletedAt is
set or isDeleted === true) has changed accordingly; also ensure the API delete
handler for packs (and other user content handlers) implements soft-delete
semantics in the DB layer so the test verifies the intended contract.
packages/mcp/src/tools/weather.ts (2)

42-43: Redundant String() conversion.

locationId is already typed as string (or undefined, but that's guarded above). The String() call is unnecessary.

♻️ Remove redundant conversion
-        const forecast = await agent.api.get('/weather/forecast', { id: String(locationId) });
+        const forecast = await agent.api.get('/weather/forecast', { id: locationId });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/mcp/src/tools/weather.ts` around lines 42 - 43, The call to
agent.api.get('/weather/forecast', { id: String(locationId) }) performs a
redundant String() conversion because locationId is already a string (or guarded
as defined); update the call in the weather code to pass id: locationId directly
(keeping the surrounding guard logic intact) so the fetch uses
agent.api.get('/weather/forecast', { id: locationId }) and then return
ok(forecast) as before.

29-35: Type assertions could be simplified.

The double casting through Record<string, unknown> is functional but verbose. Since the generic already defines the expected shape, consider using optional chaining directly on searchResults:

♻️ Simplified type handling
-        const locationId =
-          (searchResults as Record<string, unknown>).id ??
-          ((searchResults as Record<string, unknown>).results as Array<{ id: string }>)?.[0]?.id;
+        const locationId = searchResults.id ?? searchResults.results?.[0]?.id;

If TypeScript complains about the generic type inference, narrowing with an explicit type guard or adjusting the generic return type of agent.api.get would be cleaner than the double assertion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/mcp/src/tools/weather.ts` around lines 29 - 35, Replace the verbose
double-cast when deriving locationId: use the typed response from agent.api.get
and access properties with optional chaining on searchResults (e.g.,
searchResults?.id ?? searchResults?.results?.[0]?.id) instead of casting to
Record<string, unknown>; if TypeScript still complains, tighten the generic
return type of agent.api.get or add a small type guard that narrows
searchResults to the expected { id?: string; results?: Array<{ id: string }> }
shape before computing locationId.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/api/src/routes/admin/index.ts`:
- Around line 1151-1153: The PG foreign-key conflict check currently prefers
(error as { code?: string }).code over (error as { cause?: { code?: string }
}).cause?.code, which can mask PostgreSQL 23503 in wrapped errors; update the
logic around the pgCode variable in the admin route to read the nested
cause.code first (i.e., check error.cause?.code before error.code) so the
conditional if (pgCode === '23503') correctly detects FK violations and returns
409; modify the extraction used where pgCode is declared (the variable named
pgCode) to prefer cause.code then fall back to error.code.

In `@packages/api/test/packs.test.ts`:
- Around line 72-75: The beforeEach currently calls seedAndLoginTestUser() for
the regular user then calls seedAndLoginTestUser({ role: 'ADMIN', ... }) which
switches the active JWT to admin; to keep the default auth subject as the
regular testUser, create the admin account without changing the active
login—replace the second call with a non-login seeder (e.g., seedTestUser({
role: 'ADMIN', email: 'admin@example.com' })) or otherwise ensure testUser is
re-assigned by calling seedAndLoginTestUser() for the regular user after
creating the admin; update references around beforeEach, seedAndLoginTestUser,
seedTestUser and testUser accordingly.

In `@packages/api/test/setup.ts`:
- Around line 551-555: The beforeEach in the test setup currently only resets
JWT subjects via clearCurrentTestUsers and fails to clear the global override
__mockContainerFetch, allowing container-response state to leak between tests;
update the beforeEach (in packages/api/test/setup.ts) to reset
globalThis.__mockContainerFetch (e.g., set to undefined/null) as part of the
per-test teardown so each test starts with a clean mock, keeping
clearCurrentTestUsers and the existing early return behavior intact.
- Around line 242-245: The mock override for CatalogService.batchVectorSearch
currently returns Promise<any>; replace that with the concrete signature from
the real service: Promise<{ items: (Omit<CatalogItem, 'embedding'> & {
similarity: number })[][] }>, i.e. change the method signature on the test's
CatalogService class to use this exact return type (and remove the biome-ignore
any suppression) so the mock matches CatalogService.batchVectorSearch's real
type.

In `@packages/mcp/src/index.ts`:
- Around line 43-46: The State interface currently persisting authToken should
be changed to avoid storing raw JWTs: remove authToken from the State interface
and replace it with an opaque/encrypted short-lived session reference (e.g.,
sessionRef or encryptedSession) or no persisted credential at all, and update
all Durable Object usages that call setState (and any methods referencing
State.authToken) to accept the JWT only as a request-scoped parameter and not
write it to storage; audit functions around the State definition and the code
regions referenced near lines 76-86 to stop persisting the raw token and instead
persist only a non-secret session identifier or rely on per-request auth
handling.

In `@packages/mcp/src/tools/catalog.ts`:
- Around line 166-177: The current sorts treat 0 as missing because they use
(Number(...) || 999999); update the sort callbacks (the comparison.sort for
weightGrams and the cheapest calculation for priceCents) to explicitly detect
non-numeric/missing values instead of falsy 0. For example, compute
Number(a.weightGrams) and Number(b.weightGrams) into locals and use isFinite (or
isNaN) to decide whether to use that numeric value or the large fallback
(999999); do the same for Number(...priceCents) in the cheapest sort. Keep the
highestRated logic unchanged unless you also want to treat NaN differently.
Ensure you reference the comparison.sort call and the priceCents/weightGrams
properties when making the change.

In `@packages/mcp/src/tools/knowledge.ts`:
- Around line 67-95: The execute_sql_query tool currently forwards any query to
agent.api.post without enforcing the read-only constraint; add a local
validation inside the registered handler (the async ({ query, limit }) => { ...
} block registered via agent.server.registerTool for 'execute_sql_query') that
rejects queries which are not single SELECT statements — e.g., use a simple
whitelist/regex to ensure the query begins with SELECT (case-insensitive),
contains no forbidden keywords like INSERT, UPDATE, DELETE, DROP, ALTER, or
multiple statements/semicolons, and return err(...) with a clear validation
message if the check fails; keep the backend validation but prevent non-read
queries from ever being forwarded from this tool.

In `@packages/mcp/src/tools/packs.ts`:
- Around line 160-183: The tool description for add_pack_item promises "either
catalog_item_id or custom item details" but the inputSchema currently always
requires name, category, and weight_grams; update the inputSchema (the
inputSchema object inside the add_pack_item tool definition) to enforce the
either/or contract: implement a Zod union or a Zod object with a .refine() that
accepts either an object with catalog_item_id (number) or an object with name,
category, and weight_grams (and optional quantity/is_consumable/is_worn/notes),
e.g., replace the current flat schema with two alternatives (one requiring
catalog_item_id only, one requiring name+category+weight_grams) or add a refine
that checks (Boolean(catalog_item_id) || (name && category && typeof
weight_grams === 'number')); keep the existing field descriptions and defaults
but ensure validation matches the advertised behavior.
- Around line 110-127: The update handler currently allows `{ pack_id }` only
requests which build a body containing only localUpdatedAt and still call
agent.api.patch, causing needless writes; in the async handler (the function
starting with async ({ pack_id, name, description, category, is_public, tags })
=> { ... }) after building the body variable, add a guard that checks whether
any of the updatable fields (name, description, category, is_public, tags) were
provided and if none were, return a 4xx error (or throw a BadRequest) with a
clear message like "No fields to update" and do not call agent.api.patch; ensure
you check the same properties you used to populate body so the guard correctly
detects an empty update.

In `@packages/mcp/src/tools/trips.ts`:
- Around line 65-70: Validate location inputs as atomic: change the handling and
schema for the fields location_name, latitude, and longitude so they are
all-or-nothing — require either none of them or all of them. Update the Zod
schema for those fields to add a refinement (or a custom validator) that rejects
requests where only a subset is provided. In the create path (where location:
null is sent when only location_name is present) stop dropping partial input and
instead return/throw a validation error if the trio is incomplete; in the update
path (where latitude/longitude are accepted independently) reject updates that
provide only one coordinate and only apply updates when both latitude and
longitude (and optionally location_name) are present. Ensure error messages
reference the fields location_name, latitude, longitude so callers understand
the all-or-nothing requirement.

In `@packages/web-ui/src/components/calendar.tsx`:
- Around line 12-17: The Chevron component currently only renders ChevronRight
or ChevronLeft and drops react-day-picker props; update the Chevron component to
accept and forward className, disabled, and size (in addition to orientation?:
'left'|'right'|'up'|'down'), and handle all orientation values by rendering the
appropriate icon (or reusing ChevronLeft/ChevronRight with rotation for
'up'/'down') while passing the forwarded props through to the rendered icon
elements (ensure you reference Chevron, ChevronRight, ChevronLeft, and the props
className/disabled/size when making the change).

In `@tsconfig.json`:
- Line 38: The CI is not running MCP's typecheck because root tsconfig.json
excludes "packages/mcp" and the CI only runs the root-level typecheck; add a new
job step in .github/workflows/check-types.yml to execute the MCP typecheck by
running the repository's check-types script for that package (run "bun run --cwd
packages/mcp check-types") immediately after the root typecheck step so MCP's
types are validated in CI; ensure the step uses the same runner/context and
fails the job on non-zero exit.

---

Outside diff comments:
In `@packages/api/src/routes/chat.ts`:
- Around line 362-379: The handler accepts a valid integer ID but always returns
{ success: true } even when no row is updated; change the code that runs
db.update(reportedContent).set(...).where(eq(reportedContent.id, id)) to capture
the update result and check whether any rows were affected (e.g., inspect the
returned row count/affectedRows from the update call). If zero rows were
updated, return c.json({ error: 'Report not found' }, 404); otherwise continue
to return the success response. Ensure you perform this check immediately after
the update and before the final return.

In `@packages/api/test/utils/db-helpers.ts`:
- Around line 39-61: Update the outdated comment above seedTestUser to remove
the claim that it sets the JWT subject/currentTestUser and instead state that
seedTestUser only creates a user in the DB and does NOT authenticate; mention
that tests which need an authenticated context should call
seedAndLoginTestUser() or use apiWithAuthAs/apiWithBasicAuth/loginAs to set
JWT/basic auth credentials. Refer to seedTestUser, seedAndLoginTestUser,
loginAs, apiWithAuthAs, and apiWithBasicAuth in the updated comment so callers
know the correct helpers to use.

---

Nitpick comments:
In `@packages/api/package.json`:
- Line 61: Remove the duplicate devDependency entry for "drizzle-orm" in
package.json (the devDependencies entry where "drizzle-orm": "^0.45.2" is
listed); since "drizzle-orm" is already declared under dependencies (same
version), delete the devDependencies key/value pair to avoid duplication and
keep a single source of truth for the package.

In `@packages/api/test/admin.test.ts`:
- Around line 131-137: The test only asserts a 200 response for DELETE but
doesn't verify the soft-delete side effect; update the test that uses
seedTestUser, seedPack and apiWithBasicAuth to read the pack back from the
database (via the Pack model/repository used in tests) after the DELETE and
assert the soft-delete marker (e.g., deletedAt is set or isDeleted === true) has
changed accordingly; also ensure the API delete handler for packs (and other
user content handlers) implements soft-delete semantics in the DB layer so the
test verifies the intended contract.

In `@packages/api/test/auth.test.ts`:
- Around line 199-219: Add a DB-level assertion after the verify-email request
to ensure the user's emailVerified flag was persisted: after calling
authApi('/verify-email', ...) and asserting response success, query the test
database using the existing createDb instance (e.g., db.select(...).from(users)
or appropriate query helper) to fetch the user by user.id (created via
createTestUser) and assert that the returned record has emailVerified === true;
this ensures the handler not only returns success but also updates the users
table accordingly.

In `@packages/mcp/src/tools/weather.ts`:
- Around line 42-43: The call to agent.api.get('/weather/forecast', { id:
String(locationId) }) performs a redundant String() conversion because
locationId is already a string (or guarded as defined); update the call in the
weather code to pass id: locationId directly (keeping the surrounding guard
logic intact) so the fetch uses agent.api.get('/weather/forecast', { id:
locationId }) and then return ok(forecast) as before.
- Around line 29-35: Replace the verbose double-cast when deriving locationId:
use the typed response from agent.api.get and access properties with optional
chaining on searchResults (e.g., searchResults?.id ??
searchResults?.results?.[0]?.id) instead of casting to Record<string, unknown>;
if TypeScript still complains, tighten the generic return type of agent.api.get
or add a small type guard that narrows searchResults to the expected { id?:
string; results?: Array<{ id: string }> } shape before computing locationId.

In `@packages/web-ui/src/components/resizable.tsx`:
- Around line 8-15: The wrapper ResizablePanelGroup should accept the legacy
prop name "direction" and forward it as "orientation" to
ResizablePrimitive.Group to avoid breaking external consumers; update the
component to destructure props (e.g., const { direction, orientation, ...rest }
= props), compute const finalOrientation = orientation ?? direction, and pass
orientation={finalOrientation} along with {...rest} into
ResizablePrimitive.Group (preferring orientation when both present) so external
callers using the old prop continue to work.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d14c194d-448e-4ddc-9d44-7f712b0097ad

📥 Commits

Reviewing files that changed from the base of the PR and between bead001 and 97288e1.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (70)
  • .env.example
  • .github/scripts/env.ts
  • .gitignore
  • apps/admin/app/login/page.tsx
  • apps/admin/lib/api.ts
  • apps/admin/package.json
  • apps/admin/wrangler.jsonc
  • apps/expo/app.config.ts
  • apps/expo/components/Icon/Icon.ios.tsx
  • apps/expo/package.json
  • apps/expo/polyfills.js
  • apps/guides/package.json
  • apps/landing/package.json
  • package.json
  • packages/analytics/package.json
  • packages/api/container_src/package.json
  • packages/api/package.json
  • packages/api/src/routes/admin/index.ts
  • packages/api/src/routes/catalog/deleteCatalogItemRoute.ts
  • packages/api/src/routes/catalog/getCatalogItemRoute.ts
  • packages/api/src/routes/catalog/getSimilarCatalogItemsRoute.ts
  • packages/api/src/routes/catalog/updateCatalogItemRoute.ts
  • packages/api/src/routes/chat.ts
  • packages/api/src/utils/routeParams.ts
  • packages/api/test/admin.test.ts
  • packages/api/test/auth.test.ts
  • packages/api/test/catalog.test.ts
  • packages/api/test/chat.test.ts
  • packages/api/test/generate-from-online-content.test.ts
  • packages/api/test/image-detection.test.ts
  • packages/api/test/pack-templates.test.ts
  • packages/api/test/packs.test.ts
  • packages/api/test/setup.ts
  • packages/api/test/upload.test.ts
  • packages/api/test/utils/db-helpers.ts
  • packages/api/vitest.config.ts
  • packages/api/wrangler.jsonc
  • packages/cli/package.json
  • packages/guards/package.json
  • packages/mcp/.dev.vars.example
  • packages/mcp/package.json
  • packages/mcp/src/__tests__/auth.test.ts
  • packages/mcp/src/__tests__/client.test.ts
  • packages/mcp/src/__tests__/helpers.ts
  • packages/mcp/src/__tests__/tools/catalog.test.ts
  • packages/mcp/src/__tests__/tools/knowledge.test.ts
  • packages/mcp/src/__tests__/tools/packs.test.ts
  • packages/mcp/src/__tests__/tools/trail-conditions.test.ts
  • packages/mcp/src/__tests__/tools/trips.test.ts
  • packages/mcp/src/__tests__/tools/weather.test.ts
  • packages/mcp/src/client.ts
  • packages/mcp/src/index.ts
  • packages/mcp/src/prompts.ts
  • packages/mcp/src/resources.ts
  • packages/mcp/src/tools/catalog.ts
  • packages/mcp/src/tools/knowledge.ts
  • packages/mcp/src/tools/packs.ts
  • packages/mcp/src/tools/trail-conditions.ts
  • packages/mcp/src/tools/trips.ts
  • packages/mcp/src/tools/weather.ts
  • packages/mcp/src/types.ts
  • packages/mcp/tsconfig.json
  • packages/mcp/vitest.config.ts
  • packages/mcp/wrangler.jsonc
  • packages/ui/package.json
  • packages/web-ui/package.json
  • packages/web-ui/src/components/calendar.tsx
  • packages/web-ui/src/components/chart.tsx
  • packages/web-ui/src/components/resizable.tsx
  • tsconfig.json

Comment thread packages/api/src/routes/admin/index.ts
Comment thread packages/api/test/packs.test.ts
Comment thread packages/api/test/setup.ts
Comment thread packages/api/test/setup.ts
Comment thread packages/mcp/src/index.ts
Comment thread packages/mcp/src/tools/packs.ts
Comment thread packages/mcp/src/tools/packs.ts
Comment thread packages/mcp/src/tools/trips.ts
Comment thread packages/web-ui/src/components/calendar.tsx Outdated
Comment thread tsconfig.json
@mikib0
Copy link
Copy Markdown
Collaborator Author

mikib0 commented Apr 16, 2026

@copilot apply changes based on the comments in this thread

…ng seedTestUser comments

Agent-Logs-Url: https://github.com/PackRat-AI/PackRat/sessions/b373def1-54af-43ec-918c-655865c71306

Co-authored-by: mikib0 <54102880+mikib0@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

@copilot apply changes based on the comments in this thread

Applied all three changes in 982e347:

  1. calendar.tsx: Updated Chevron to explicitly handle 'up'ChevronUp and 'down'ChevronDown, in addition to the existing 'right' / 'left' cases. Also imported ChevronUp and ChevronDown from lucide-react.

  2. packs.test.ts (×2): Replaced the inaccurate // NOTE: seedTestUser also sets currentTestUser… comment with a clearer // Create a different user and their pack; capture testUser.id before seeding the other user in both the "prevents updating" and "prevents deleting" tests.

@mikib0 mikib0 merged commit f97bc7f into main Apr 16, 2026
9 of 14 checks passed
@mikib0 mikib0 deleted the release/2.0.20 branch April 16, 2026 11:58
@coderabbitai coderabbitai Bot mentioned this pull request Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api ci/cd dependencies Pull requests that update a dependency file mobile web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants