Inspiration
You ask your Bee for "a quiet cafe I haven't been to", then you still open a maps app, scroll, and half the results are places you went last week. Bee already remembers where you've been. Bee Nav lets that memory make the decision.
What it does
Say a navigation-style request to your Bee ("find me a quiet cafe I haven't been to", "take me to a bookstore I haven't been to"). Bee Nav:
- reads your current location and your last 30 days of visits through the Bee CLI commands (
bee locations current,bee locations recent,bee now), - searches Google Places for what's actually open nearby,
- picks one place, skips the ones you visited recently and says so ("I skipped Storyville Coffee since you were there recently"),
- returns a walking route that starts from where Bee says you are, as a button and a QR code for your phone.
If nothing good is open, it says so instead of confidently sending you to a closed storefront.
Demo disclosure: I don't have a Bee device or an Apple Watch running Bee, so the demo video runs on Bee Nav's built-in Bee simulator. It answers the same bee locations current|recent and bee now commands as the real CLI, and the app labels it SIMULATED in the header badge, the input box, the API (simulated: true) and the footer. Amazon Bedrock, Google Places and the routes in the video are live. With the real Bee CLI installed and logged in, npm start reads real Bee data with no code change (src/services/bee.js).
How I built it
- Reasoning: a Strands Agents SDK agent on Amazon Bedrock (Claude Haiku 5.5 via
us.anthropic.claude-haiku-5-5, configurable withBEDROCK_MODEL), a freshAgentper request, with five zod-typed tools called in order:get_current_bee_location,get_recent_bee_visits,search_places,get_place_details,build_navigation_url(src/agent/strands.js,src/agent/tools.js). It is not allowed to recommend a place search didn't return. - Ranking: open-now first, then type match (a grocery store never beats a real cafe), then preference words, then rating. Visit de-duplication uses token-overlap name matching plus a 75 m coordinate fallback, so "Storyville Coffee" (Bee) matches "Storyville Coffee Company" (Places).
- Bee data:
src/services/bee.jsshells out to the Bee CLI with--jsonand shape-tolerant parsers;src/services/beesim.jsis the simulator with the same grammar. - Honesty in the UI: every answer shows which engine ran (
bedrock+strandsor the deterministic fallback) and which data source fed it (Bee CLI, simulator, cache or sample). - Privacy: the server binds to
127.0.0.1by default because it exposes real-time position and 30-day movement history; phone access is token-gated. - Stack: Node 22+, Express 5, Strands Agents SDK, Amazon Bedrock, Google Places API (New), Leaflet with Esri tiles, QR codes. 71 self-tests (
npm run selftest). MIT license.
Challenges I ran into
- No Bee hardware and no developer sandbox, so I built a simulator that speaks the CLI's grammar and is labelled everywhere.
- Strands'
AgentResulthas no.text; reading it wrong returnednullwhile the health check still said Bedrock was up. Now the engine label needs a real reply and a realbuild_navigation_urlcall. - On a live run a grocery store beat a real cafe because the cafes were closed; fixed with strictest-first ranking and an honest "looks closed, say go anyway" reply.
- The route link had no origin, so a phone scanning the QR planned the walk from the phone's location; it now starts from Bee's location.
Accomplishments that I'm proud of
The answer explains itself: it names what it skipped and why, it says when it can't verify "quiet", and it never pretends simulated data is real.
What I learned
"The SDK call succeeded" and "the agent actually answered" are different claims. Health checks should check content.
What's next for Bee Nav
Run it on a real Bee, react to new requests with a push feed instead of polling, and add "somewhere new" for food, parks and gyms with the same memory.
Built With
- amazon-bedrock
- bee-cli
- claude
- express.js
- google-places
- javascript
- leaflet.js
- node.js
- strands-agents
Log in or sign up for Devpost to join the conversation.