tripkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/agent/AGENT-SKILL.md +105 -0
- package/agent/questionnaire.yaml +182 -0
- package/convert.js +65 -0
- package/docs/README.md +1 -0
- package/docs/screenshot.png +0 -0
- package/examples/oregon-spring-2026.yaml +588 -0
- package/package.json +52 -0
- package/renderers/html/tripkit-renderer.html +446 -0
- package/schema/tripkit.schema.yaml +132 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peter Kwidzinski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# πΊοΈ TripKit
|
|
2
|
+
|
|
3
|
+
**Open-source framework for AI-assisted trip planning with beautiful interactive visualizers.**
|
|
4
|
+
|
|
5
|
+
TripKit is a structured data schema + rendering engine that turns trip plans into stunning interactive maps with day-by-day itineraries. It works with any AI agent (Claude, GPT, Gemini) or can be filled in manually.
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="docs/screenshot.png" alt="TripKit Visualizer" width="800">
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
## Why TripKit?
|
|
12
|
+
|
|
13
|
+
Most trip planning tools give you either:
|
|
14
|
+
- **A map with pins** (no context, no schedule, no restaurants)
|
|
15
|
+
- **A text itinerary** (no visual, hard to share, impossible to navigate from)
|
|
16
|
+
|
|
17
|
+
TripKit gives you **both** β a Leaflet interactive map with route polylines, stop markers, and hotel markers, alongside a rich sidebar with weather, meals, lodging confirmations, alerts, and pro tips for each day.
|
|
18
|
+
|
|
19
|
+
Born from a real 6-day Oregon road trip planned iteratively with AI. Every feature exists because we needed it on the road.
|
|
20
|
+
|
|
21
|
+
## How It Works
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
25
|
+
β 1. QUESTIONNAIRE β
|
|
26
|
+
β Conversational elicitation β Trip Brief β
|
|
27
|
+
βββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
28
|
+
β 2. RESEARCH & PLANNING β
|
|
29
|
+
β Trip Brief β Trip Plan (YAML) β
|
|
30
|
+
βββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
31
|
+
β 3. RENDER β
|
|
32
|
+
β YAML β Interactive HTML or React app β
|
|
33
|
+
βββββββββββββββββββββββββββββββββββββββββββββββ€
|
|
34
|
+
β 4. ITERATE β
|
|
35
|
+
β Feedback β Updated YAML β Re-render β
|
|
36
|
+
βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**The YAML schema is the product.** Renderers are interchangeable. The AI layer is optional but powerful.
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
### Option 1: One-liner via `npx` (recommended)
|
|
44
|
+
|
|
45
|
+
**Prerequisite:** [Node.js](https://nodejs.org) 18 or newer. No install, no clone.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx tripkit my-trip.yaml my-trip.html
|
|
49
|
+
open my-trip.html
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
That's it β `npx` fetches TripKit on first run and caches it. Use any YAML path on your machine.
|
|
53
|
+
|
|
54
|
+
### Option 2: Clone the repo (for hacking on the renderer)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git clone https://github.com/piti/tripkit.git
|
|
58
|
+
cd tripkit
|
|
59
|
+
npm install
|
|
60
|
+
node convert.js examples/oregon-spring-2026.yaml my-trip.html
|
|
61
|
+
open my-trip.html
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Option 3: With an AI Agent (everyone)
|
|
65
|
+
|
|
66
|
+
1. Start a conversation with your preferred AI agent (Claude recommended)
|
|
67
|
+
2. Share the `agent/AGENT-SKILL.md` as context
|
|
68
|
+
3. Tell it about your trip: _"I'm planning a 5-day road trip through the Pacific Northwest with my family..."_
|
|
69
|
+
4. The agent uses the questionnaire to gather details, researches routes/hotels/restaurants, and generates a TripKit YAML file
|
|
70
|
+
5. Convert to HTML with `npx tripkit your-trip.yaml`, or ask the agent to render it directly
|
|
71
|
+
|
|
72
|
+
### Option 4: Manual (no AI needed)
|
|
73
|
+
|
|
74
|
+
1. Copy `examples/oregon-spring-2026.yaml` as a starting template
|
|
75
|
+
2. Edit with your own trip data
|
|
76
|
+
3. Run `npx tripkit your-trip.yaml`
|
|
77
|
+
4. Open the generated HTML file
|
|
78
|
+
|
|
79
|
+
## Project Structure
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
tripkit/
|
|
83
|
+
βββ schema/
|
|
84
|
+
β βββ tripkit.schema.yaml # Data contract β the spec
|
|
85
|
+
βββ examples/
|
|
86
|
+
β βββ oregon-spring-2026.yaml # Complete real-world example
|
|
87
|
+
βββ renderers/
|
|
88
|
+
β βββ html/
|
|
89
|
+
β β βββ tripkit-renderer.html # Self-contained HTML renderer
|
|
90
|
+
β βββ react/
|
|
91
|
+
β βββ (coming soon) # React component library
|
|
92
|
+
βββ agent/
|
|
93
|
+
β βββ questionnaire.yaml # Elicitation template
|
|
94
|
+
β βββ AGENT-SKILL.md # System prompt for AI agents
|
|
95
|
+
βββ docs/
|
|
96
|
+
β βββ screenshot.png
|
|
97
|
+
βββ convert.js # YAML β HTML CLI tool
|
|
98
|
+
βββ package.json
|
|
99
|
+
βββ README.md
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Schema Overview
|
|
103
|
+
|
|
104
|
+
The YAML schema captures everything needed for a complete trip plan:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
trip: # Title, dates, travelers, origin
|
|
108
|
+
days: # Array of day plans, each containing:
|
|
109
|
+
- number # Day number
|
|
110
|
+
title # Route summary
|
|
111
|
+
date # Date string
|
|
112
|
+
status # completed | active | upcoming
|
|
113
|
+
color # Map route color (hex)
|
|
114
|
+
summary # Drive time, hike time, miles
|
|
115
|
+
weather # Forecast (filled closer to trip)
|
|
116
|
+
meals # Breakfast, lunch, dinner recommendations
|
|
117
|
+
lodging # Hotel name, confirmation, coordinates
|
|
118
|
+
alerts # Warnings (road closures, age restrictions)
|
|
119
|
+
tips # Pro tips from experience
|
|
120
|
+
stops # Array of stops with lat/lng, descriptions, nav links
|
|
121
|
+
routes: # Map polylines (optional β auto-generated if omitted)
|
|
122
|
+
theme: # Visual customization (colors, fonts, map style)
|
|
123
|
+
agent_context: # Preferences, constraints, iteration log (for AI agents)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
See `schema/tripkit.schema.yaml` for the complete specification.
|
|
127
|
+
|
|
128
|
+
## Features
|
|
129
|
+
|
|
130
|
+
### Interactive Map
|
|
131
|
+
- Leaflet.js with Esri terrain/satellite/NatGeo tile layers
|
|
132
|
+
- Day-colored route polylines
|
|
133
|
+
- Numbered stop markers with popup details
|
|
134
|
+
- Branded hotel markers with confirmation numbers
|
|
135
|
+
- Click a day β map zooms to that segment
|
|
136
|
+
- Click a stop β map zooms and opens popup
|
|
137
|
+
|
|
138
|
+
### Day-by-Day Sidebar
|
|
139
|
+
- Weather callouts with forecasts
|
|
140
|
+
- Alert banners (road closures, permit requirements, age restrictions)
|
|
141
|
+
- Pro tip callouts
|
|
142
|
+
- Stop cards with images, descriptions, duration, parking fees
|
|
143
|
+
- Meal recommendations (breakfast, lunch, dinner)
|
|
144
|
+
- Lodging with confirmation numbers and navigate links
|
|
145
|
+
|
|
146
|
+
### Navigation Links
|
|
147
|
+
Every stop and hotel includes a Google Maps navigation URL:
|
|
148
|
+
```
|
|
149
|
+
https://www.google.com/maps/dir/?api=1&destination=...
|
|
150
|
+
```
|
|
151
|
+
Click on your phone β opens turn-by-turn directions from your current location.
|
|
152
|
+
|
|
153
|
+
### Real-Time Adaptation
|
|
154
|
+
The schema supports iterative refinement:
|
|
155
|
+
- `status` field tracks completed/active/upcoming days
|
|
156
|
+
- `agent_context.iteration_log` captures all changes and reasoning
|
|
157
|
+
- Weather can be updated day-by-day as forecasts become available
|
|
158
|
+
- Stops can be added/removed/reordered without breaking the renderer
|
|
159
|
+
|
|
160
|
+
## Design Decisions
|
|
161
|
+
|
|
162
|
+
### Why YAML?
|
|
163
|
+
- Human-readable AND machine-writable
|
|
164
|
+
- Supports comments (JSON doesn't)
|
|
165
|
+
- Easy to hand-edit for tweaks
|
|
166
|
+
- Trivial conversion to JSON for rendering
|
|
167
|
+
|
|
168
|
+
### Why Leaflet?
|
|
169
|
+
- Free, open-source, no API key needed
|
|
170
|
+
- Works offline once tiles are cached
|
|
171
|
+
- Lightweight β entire renderer is a single HTML file
|
|
172
|
+
- Esri tile layers are beautiful and free for non-commercial use
|
|
173
|
+
|
|
174
|
+
### Why single-file HTML?
|
|
175
|
+
- Zero dependencies at runtime (Leaflet loaded from CDN)
|
|
176
|
+
- Share via email, Slack, Dropbox β recipient just opens the file
|
|
177
|
+
- Works offline (after first load caches tiles)
|
|
178
|
+
- No hosting needed
|
|
179
|
+
|
|
180
|
+
## Lessons Learned
|
|
181
|
+
|
|
182
|
+
Built from a real trip. These lessons are encoded in the agent skill:
|
|
183
|
+
|
|
184
|
+
1. **Day 1 is always the longest drive** β plan a light evening
|
|
185
|
+
2. **Families run 30-60 min behind** β build buffer, not precision
|
|
186
|
+
3. **Leave 20% slack per day** β best stops are often unplanned
|
|
187
|
+
4. **Hotel chain loyalty matters** β 5 nights = meaningful points
|
|
188
|
+
5. **Free breakfast saves $15-20/person/day** β real budget factor
|
|
189
|
+
6. **One big hike per day max** β even fit families burn out
|
|
190
|
+
7. **Verify age restrictions** β breweries and hot springs are often 21+
|
|
191
|
+
8. **Drive times are optimistic** β add 15-20% for real-world stops
|
|
192
|
+
9. **Weather changes everything** β check 2 days out and adapt
|
|
193
|
+
10. **The iteration log is gold** β captures reasoning for next trip
|
|
194
|
+
|
|
195
|
+
## Contributing
|
|
196
|
+
|
|
197
|
+
PRs welcome! Especially:
|
|
198
|
+
- [ ] React renderer component library
|
|
199
|
+
- [ ] Mobile-responsive improvements
|
|
200
|
+
- [ ] Dark mode theme
|
|
201
|
+
- [ ] YAML validation CLI tool
|
|
202
|
+
- [ ] More example trips
|
|
203
|
+
- [ ] Internationalization (metric units, languages)
|
|
204
|
+
- [ ] Export to Google My Maps
|
|
205
|
+
- [ ] Import from Google Maps saved places
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT β use it, fork it, build on it.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
*Built with β€οΈ from a real family road trip through Oregon. If you use TripKit for your next adventure, we'd love to hear about it.*
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# TripKit Agent Skill
|
|
2
|
+
# System prompt / skill for AI agents that plan trips using the TripKit framework.
|
|
3
|
+
# Agent-agnostic: works with Claude, GPT, Gemini, or any capable LLM with web search.
|
|
4
|
+
|
|
5
|
+
## Role
|
|
6
|
+
|
|
7
|
+
You are a trip planning agent that creates detailed, actionable road trip and travel plans. You use the TripKit schema to produce structured YAML data that renders into beautiful interactive trip visualizers.
|
|
8
|
+
|
|
9
|
+
## Workflow
|
|
10
|
+
|
|
11
|
+
### Phase 1: Elicitation
|
|
12
|
+
Use the questionnaire template (`agent/questionnaire.yaml`) to gather trip preferences conversationally. Don't interrogate β have a natural conversation. Extract as much as you can from the user's initial message before asking follow-ups.
|
|
13
|
+
|
|
14
|
+
**Minimum viable input to start planning:**
|
|
15
|
+
- Destination region
|
|
16
|
+
- Dates / duration
|
|
17
|
+
- Party size (adults + kids ages)
|
|
18
|
+
- Starting point
|
|
19
|
+
|
|
20
|
+
### Phase 2: Research & Draft
|
|
21
|
+
With the basics in hand, research and produce a first draft:
|
|
22
|
+
|
|
23
|
+
1. **Route research**: Search for driving routes, distances, and seasonal road conditions. Check for closures, construction, and permit requirements.
|
|
24
|
+
2. **Attraction research**: Find top-rated stops along the route. Prioritize by user interests. Check hours, fees, seasonal availability, and age restrictions.
|
|
25
|
+
3. **Lodging research**: Match user preferences (chain loyalty, budget, amenities). Compare options honestly β recommend the best fit, not just the first result.
|
|
26
|
+
4. **Meal research**: Find restaurants near each stop. Prioritize local favorites over chains.
|
|
27
|
+
5. **Produce YAML**: Generate a complete TripKit YAML file following the schema.
|
|
28
|
+
|
|
29
|
+
### Phase 3: Render
|
|
30
|
+
Convert the YAML to the interactive HTML visualizer. The visualizer includes:
|
|
31
|
+
- Leaflet terrain map with day-colored route polylines
|
|
32
|
+
- Numbered stop markers with popup details
|
|
33
|
+
- Hotel markers (BW-style or chain-branded) with confirmation numbers
|
|
34
|
+
- Day-by-day sidebar with weather, meals, lodging, alerts, tips
|
|
35
|
+
- Map layer toggle (terrain / satellite / topo)
|
|
36
|
+
|
|
37
|
+
### Phase 4: Iterate
|
|
38
|
+
The plan WILL change. This is normal. Common iteration patterns:
|
|
39
|
+
- **Rebalancing days**: One day too heavy, another too light β redistribute stops
|
|
40
|
+
- **Swapping lodging**: Better option found β update with new confirmation
|
|
41
|
+
- **Real-time adaptation**: Weather changes, road closures, fatigue β adjust same-day
|
|
42
|
+
- **Adding/removing stops**: New discovery or running behind β flex the plan
|
|
43
|
+
- **Schedule conflicts**: Work meetings, reservations β restructure around constraints
|
|
44
|
+
|
|
45
|
+
Track all changes in `agent_context.iteration_log`. Each iteration should feel like sharpening, not starting over.
|
|
46
|
+
|
|
47
|
+
## Critical Rules
|
|
48
|
+
|
|
49
|
+
### Research Standards
|
|
50
|
+
1. **Verify seasonal access**: Many parks, roads, and passes are closed seasonally. ALWAYS check.
|
|
51
|
+
2. **Check age restrictions**: Venues, breweries, hot springs β verify before recommending for families.
|
|
52
|
+
3. **Validate drive times**: Use actual routing, not straight-line estimates. Mountain roads average 30-40 mph, coastal roads 45-50 mph.
|
|
53
|
+
4. **Confirm prices and fees**: Park entrance fees, parking fees, reservation requirements change yearly.
|
|
54
|
+
5. **Cross-check with multiple sources**: One TripAdvisor review β a recommendation.
|
|
55
|
+
|
|
56
|
+
### Honest Recommendations
|
|
57
|
+
1. **Be opinionated**: Don't list 5 equal options. Recommend the best one and explain why.
|
|
58
|
+
2. **Flag tradeoffs**: "Astoria > Seaside because Goonies house + better character, but 20 min further from Cannon Beach."
|
|
59
|
+
3. **Admit mistakes**: When a recommendation doesn't work (e.g., 21+ venue for families), own it, log it, and fix it.
|
|
60
|
+
4. **Push back on bad ideas**: If the user wants to drive 14 hours with kids, suggest alternatives.
|
|
61
|
+
5. **Respect fatigue**: After a big hiking day, don't plan another big hiking day.
|
|
62
|
+
|
|
63
|
+
### Data Integrity
|
|
64
|
+
1. **Confirmation numbers**: Only add when the user confirms booking. Never fabricate.
|
|
65
|
+
2. **Weather**: Only add real forecasts close to travel date. Use placeholder text for future trips.
|
|
66
|
+
3. **Navigation URLs**: Use Google Maps format: `https://www.google.com/maps/dir/?api=1&destination=...`
|
|
67
|
+
4. **Coordinates**: Verify lat/lng are correct β a wrong decimal place puts a marker in the ocean.
|
|
68
|
+
|
|
69
|
+
## Output Format
|
|
70
|
+
|
|
71
|
+
Always produce a complete TripKit YAML file that conforms to `schema/tripkit.schema.yaml`. The YAML is the source of truth β the HTML renderer reads it.
|
|
72
|
+
|
|
73
|
+
For embedded rendering (single-file HTML), convert the YAML to JSON and embed it in the HTML template. This is the fastest path to a shareable trip plan.
|
|
74
|
+
|
|
75
|
+
## Example Iteration Patterns
|
|
76
|
+
|
|
77
|
+
### "Can we push further north to save driving tomorrow?"
|
|
78
|
+
β Recalculate day split, rebalance stops, update lodging, re-render.
|
|
79
|
+
|
|
80
|
+
### "We're tired, can we leave later?"
|
|
81
|
+
β Calculate time budget to hard stops (hotel check-in, meetings), identify skippable stops, provide revised schedule.
|
|
82
|
+
|
|
83
|
+
### "Is that parking reservation required?"
|
|
84
|
+
β Search for current requirements, cite source, update alerts in YAML.
|
|
85
|
+
|
|
86
|
+
### "What about [Alternative Hotel]?"
|
|
87
|
+
β Research, compare on price/location/amenities/loyalty, present tradeoff table, let user decide.
|
|
88
|
+
|
|
89
|
+
### "We did [Stop X] already, remove from tomorrow"
|
|
90
|
+
β Update YAML, recalculate day timing, identify what the freed time enables.
|
|
91
|
+
|
|
92
|
+
## Lessons Learned (from real trips)
|
|
93
|
+
|
|
94
|
+
These patterns emerged from actual trip planning and should inform all future plans:
|
|
95
|
+
|
|
96
|
+
1. **Day 1 is always the longest drive** β plan a light first evening, not an ambitious agenda.
|
|
97
|
+
2. **Families run 30-60 min behind schedule** β build buffer, not precision.
|
|
98
|
+
3. **The best stops are often unplanned** β leave 20% slack in each day.
|
|
99
|
+
4. **Hotel chain loyalty matters** β 5 nights at one chain = meaningful points + consistent free breakfast.
|
|
100
|
+
5. **Free breakfast saves $15-20/person/day** β it's a real budget factor for families.
|
|
101
|
+
6. **One big hike per day max** β even fit families burn out on back-to-back heavy days.
|
|
102
|
+
7. **Evening plans need kid-friendly verification** β breweries, hot springs, entertainment venues often have age restrictions that aren't obvious online.
|
|
103
|
+
8. **Drive time estimates are optimistic** β add 15-20% for mountain/coastal roads, bathroom stops, and "ooh pull over" moments.
|
|
104
|
+
9. **Weather changes everything** β check forecasts 2 days out and adapt. Rain at a lighthouse is different from rain on a hiking trail.
|
|
105
|
+
10. **The iteration log is the most valuable artifact** β it captures decision rationale for next time.
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# TripKit β Trip Planning Questionnaire
|
|
2
|
+
# This structured elicitation flow gathers the information needed
|
|
3
|
+
# to generate a trip plan. Any AI agent can use this template.
|
|
4
|
+
#
|
|
5
|
+
# USAGE:
|
|
6
|
+
# - Present questions conversationally, not as a survey
|
|
7
|
+
# - Questions are grouped by priority (must-ask β nice-to-have)
|
|
8
|
+
# - Skip questions when answers are already obvious from context
|
|
9
|
+
# - The output should populate agent_context.preferences and .constraints
|
|
10
|
+
|
|
11
|
+
# ============================================================
|
|
12
|
+
# PHASE 1: DESTINATION & DATES (must-ask)
|
|
13
|
+
# ============================================================
|
|
14
|
+
phase_1_destination:
|
|
15
|
+
- id: destination
|
|
16
|
+
question: "Where are you thinking of going? Any specific region, state, or country?"
|
|
17
|
+
type: open_text
|
|
18
|
+
follow_up: "Any must-see places or attractions?"
|
|
19
|
+
maps_to: agent_context.constraints.must_see
|
|
20
|
+
|
|
21
|
+
- id: dates
|
|
22
|
+
question: "When are you planning to go, and how many days do you have?"
|
|
23
|
+
type: open_text
|
|
24
|
+
maps_to: trip.dates, trip.total_days
|
|
25
|
+
|
|
26
|
+
- id: origin
|
|
27
|
+
question: "Where will you be starting from?"
|
|
28
|
+
type: open_text
|
|
29
|
+
maps_to: trip.origin
|
|
30
|
+
skip_if: "Known from user context/location"
|
|
31
|
+
|
|
32
|
+
# ============================================================
|
|
33
|
+
# PHASE 2: TRAVEL PARTY (must-ask)
|
|
34
|
+
# ============================================================
|
|
35
|
+
phase_2_travelers:
|
|
36
|
+
- id: party_size
|
|
37
|
+
question: "Who's coming along? Adults, kids, ages?"
|
|
38
|
+
type: open_text
|
|
39
|
+
maps_to: trip.travelers
|
|
40
|
+
why: "Kid ages affect restaurant choices, hike difficulty, lodging needs, and activity restrictions (e.g., 21+ venues)"
|
|
41
|
+
|
|
42
|
+
- id: vehicle
|
|
43
|
+
question: "How are you getting there? Car, RV, flying + rental?"
|
|
44
|
+
type: single_select
|
|
45
|
+
options: ["Car/SUV", "RV/Camper", "Flying + rental car", "Train", "Other"]
|
|
46
|
+
maps_to: trip.vehicle
|
|
47
|
+
|
|
48
|
+
# ============================================================
|
|
49
|
+
# PHASE 3: INTERESTS & STYLE (should-ask)
|
|
50
|
+
# ============================================================
|
|
51
|
+
phase_3_interests:
|
|
52
|
+
- id: interests
|
|
53
|
+
question: "What kind of experiences are you hoping for?"
|
|
54
|
+
type: multi_select
|
|
55
|
+
options:
|
|
56
|
+
- "Hiking & nature"
|
|
57
|
+
- "Beaches & coast"
|
|
58
|
+
- "Food & restaurants"
|
|
59
|
+
- "History & culture"
|
|
60
|
+
- "Photography"
|
|
61
|
+
- "Adventure sports"
|
|
62
|
+
- "Relaxation & spa"
|
|
63
|
+
- "Shopping & towns"
|
|
64
|
+
- "Wildlife"
|
|
65
|
+
- "Scenic drives"
|
|
66
|
+
- "Family activities"
|
|
67
|
+
- "Nightlife & entertainment"
|
|
68
|
+
maps_to: agent_context.preferences.interests
|
|
69
|
+
|
|
70
|
+
- id: pace
|
|
71
|
+
question: "How packed do you want the days?"
|
|
72
|
+
type: single_select
|
|
73
|
+
options:
|
|
74
|
+
- label: "Relaxed"
|
|
75
|
+
description: "Sleep in, 1β2 stops per day, lots of downtime"
|
|
76
|
+
- label: "Moderate"
|
|
77
|
+
description: "Balanced β 3β4 stops with breaks between"
|
|
78
|
+
- label: "Packed"
|
|
79
|
+
description: "See everything! Early mornings, full days"
|
|
80
|
+
maps_to: agent_context.preferences.pace
|
|
81
|
+
|
|
82
|
+
- id: max_drive
|
|
83
|
+
question: "How much driving per day is comfortable for your group?"
|
|
84
|
+
type: single_select
|
|
85
|
+
options:
|
|
86
|
+
- "Under 3 hours"
|
|
87
|
+
- "3β5 hours"
|
|
88
|
+
- "5β7 hours"
|
|
89
|
+
- "Whatever it takes"
|
|
90
|
+
maps_to: agent_context.constraints.max_drive_per_day
|
|
91
|
+
|
|
92
|
+
# ============================================================
|
|
93
|
+
# PHASE 4: ACCOMMODATION (should-ask)
|
|
94
|
+
# ============================================================
|
|
95
|
+
phase_4_lodging:
|
|
96
|
+
- id: budget
|
|
97
|
+
question: "What's your nightly lodging budget?"
|
|
98
|
+
type: single_select
|
|
99
|
+
options:
|
|
100
|
+
- label: "Budget ($50β100)"
|
|
101
|
+
description: "Motels, hostels, basic hotels"
|
|
102
|
+
- label: "Mid-range ($100β180)"
|
|
103
|
+
description: "Quality hotels, nice B&Bs"
|
|
104
|
+
- label: "Upscale ($180β300)"
|
|
105
|
+
description: "Boutique hotels, resorts"
|
|
106
|
+
- label: "Luxury ($300+)"
|
|
107
|
+
description: "Top-tier resorts, unique stays"
|
|
108
|
+
- label: "Mixed"
|
|
109
|
+
description: "Save on some nights, splurge on others"
|
|
110
|
+
maps_to: agent_context.preferences.budget
|
|
111
|
+
|
|
112
|
+
- id: lodging_style
|
|
113
|
+
question: "Any accommodation preferences?"
|
|
114
|
+
type: multi_select
|
|
115
|
+
options:
|
|
116
|
+
- "Hotel chain loyalty program (specify which)"
|
|
117
|
+
- "Unique/boutique stays"
|
|
118
|
+
- "Airbnb/vacation rentals"
|
|
119
|
+
- "Camping/glamping"
|
|
120
|
+
- "Must have pool"
|
|
121
|
+
- "Must have free breakfast"
|
|
122
|
+
- "Must have kitchen/kitchenette"
|
|
123
|
+
- "Pet-friendly needed"
|
|
124
|
+
maps_to: agent_context.preferences.accommodation_chain
|
|
125
|
+
follow_up_if: "loyalty program selected β Which chain? Any existing membership?"
|
|
126
|
+
|
|
127
|
+
# ============================================================
|
|
128
|
+
# PHASE 5: CONSTRAINTS (ask if relevant)
|
|
129
|
+
# ============================================================
|
|
130
|
+
phase_5_constraints:
|
|
131
|
+
- id: avoid
|
|
132
|
+
question: "Anything you want to avoid? (traffic, tolls, highways, specific areas)"
|
|
133
|
+
type: open_text
|
|
134
|
+
maps_to: agent_context.constraints.avoid
|
|
135
|
+
|
|
136
|
+
- id: dietary
|
|
137
|
+
question: "Any dietary needs for restaurant recommendations?"
|
|
138
|
+
type: open_text
|
|
139
|
+
maps_to: agent_context.preferences.dietary
|
|
140
|
+
skip_if: "Not a food-focused trip"
|
|
141
|
+
|
|
142
|
+
- id: mobility
|
|
143
|
+
question: "Any mobility considerations? (wheelchair access, stroller, limited hiking ability)"
|
|
144
|
+
type: open_text
|
|
145
|
+
maps_to: agent_context.preferences.mobility
|
|
146
|
+
|
|
147
|
+
- id: schedule_blocks
|
|
148
|
+
question: "Any time commitments during the trip? (work calls, events, reservations)"
|
|
149
|
+
type: open_text
|
|
150
|
+
maps_to: agent_context.constraints.schedule_blocks
|
|
151
|
+
|
|
152
|
+
# ============================================================
|
|
153
|
+
# PHASE 6: NICE-TO-HAVE (only if conversation flows naturally)
|
|
154
|
+
# ============================================================
|
|
155
|
+
phase_6_extras:
|
|
156
|
+
- id: previous_trips
|
|
157
|
+
question: "Have you been to this area before? Anything you've already done?"
|
|
158
|
+
type: open_text
|
|
159
|
+
why: "Avoids recommending things they've already seen"
|
|
160
|
+
|
|
161
|
+
- id: trip_style
|
|
162
|
+
question: "Is this more of a 'see everything once' trip or a 'find a spot and settle in' trip?"
|
|
163
|
+
type: single_select
|
|
164
|
+
options: ["Road trip β see everything", "Hub & spoke β base camp + day trips", "Mix of both"]
|
|
165
|
+
|
|
166
|
+
- id: photography
|
|
167
|
+
question: "Is photography a priority? (affects timing for golden hour, sunrise spots)"
|
|
168
|
+
type: boolean
|
|
169
|
+
why: "Changes arrival times at scenic stops"
|
|
170
|
+
|
|
171
|
+
# ============================================================
|
|
172
|
+
# AGENT INSTRUCTIONS
|
|
173
|
+
# ============================================================
|
|
174
|
+
agent_notes:
|
|
175
|
+
- "Present these conversationally β NOT as a numbered survey."
|
|
176
|
+
- "Group related questions naturally. Don't ask all 15 one by one."
|
|
177
|
+
- "Phase 1-2 are essential. Phase 3-4 are important. Phase 5-6 are situational."
|
|
178
|
+
- "After Phase 1-2, you can start researching and present Phase 3-4 alongside initial ideas."
|
|
179
|
+
- "The questionnaire is a starting point, not a rigid script. Adapt to the user's energy."
|
|
180
|
+
- "If the user gives a wall of text with lots of info, extract answers β don't re-ask."
|
|
181
|
+
- "Always validate: road closures, seasonal access, permit requirements, age restrictions."
|
|
182
|
+
- "Respect the iteration_log pattern β the plan WILL change. That's the process, not a failure."
|
package/convert.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* TripKit CLI β Convert YAML trip data to interactive HTML
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
let yaml;
|
|
10
|
+
try {
|
|
11
|
+
yaml = require('js-yaml');
|
|
12
|
+
} catch (e) {
|
|
13
|
+
console.error('Missing dependency. Run: npm install (from the tripkit directory)');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const invokedAs = path.basename(process.argv[1] || 'tripkit') === 'convert.js'
|
|
18
|
+
? 'node convert.js'
|
|
19
|
+
: 'tripkit';
|
|
20
|
+
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
if (args.length === 0 || args[0] === '-h' || args[0] === '--help') {
|
|
23
|
+
console.log(`
|
|
24
|
+
TripKit β Convert YAML trip data to interactive HTML
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
${invokedAs} <trip.yaml> [output.html]
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
${invokedAs} my-trip.yaml my-trip.html
|
|
31
|
+
|
|
32
|
+
Flags:
|
|
33
|
+
-h, --help Show this help
|
|
34
|
+
-v, --version Show version
|
|
35
|
+
`);
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (args[0] === '-v' || args[0] === '--version') {
|
|
40
|
+
console.log(require(path.join(__dirname, 'package.json')).version);
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const inputFile = args[0];
|
|
45
|
+
const outputFile = args[1] || inputFile.replace(/\.ya?ml$/, '.html');
|
|
46
|
+
|
|
47
|
+
// Read and parse YAML
|
|
48
|
+
const yamlContent = fs.readFileSync(inputFile, 'utf8');
|
|
49
|
+
const tripData = yaml.load(yamlContent);
|
|
50
|
+
|
|
51
|
+
// Read HTML template
|
|
52
|
+
const templatePath = path.join(__dirname, 'renderers', 'html', 'tripkit-renderer.html');
|
|
53
|
+
let template = fs.readFileSync(templatePath, 'utf8');
|
|
54
|
+
|
|
55
|
+
// Embed trip data into template
|
|
56
|
+
const jsonData = JSON.stringify(tripData, null, 2);
|
|
57
|
+
template = template.replace(
|
|
58
|
+
'const TRIP_DATA = {};',
|
|
59
|
+
`const TRIP_DATA = ${jsonData};`
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Write output
|
|
63
|
+
fs.writeFileSync(outputFile, template, 'utf8');
|
|
64
|
+
console.log(`β
Generated: ${outputFile}`);
|
|
65
|
+
console.log(` ${tripData.trip.title} β ${tripData.trip.total_days} days, ${tripData.trip.total_stops} stops`);
|
package/docs/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Screenshot placeholder β replace with actual screenshot of the TripKit visualizer
|
|
Binary file
|