Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,14 @@ git clone https://github.com/mynextadventure/mna-cli
cd mna-cli
bun install
bun run codegen
bun run build
bun link
```

`bun run build` is required before `bun link` — it produces `dist/mna.js`, the bin
target. `bun link` only creates the `mna` symlink if that file already exists, so
skipping the build leaves you with `command not found: mna`.

`mna` should then be on your PATH. See [DEVELOPMENT.md](./DEVELOPMENT.md).

## Quickstart
Expand Down Expand Up @@ -126,17 +131,17 @@ Every command supports `--json` for piping into `jq` or Claude.

| Command | Description |
|---|---|
| `mna destinations add <tripId> <variantId> --place <name> [--notes=...] [--return-to-home]` | Add a destination. |
| `mna destinations edit <tripId> <variantId> <destinationKey> [--place=...] [--notes=...] [--no-return-to-home]` | Update destination. |
| `mna destinations add <tripId> <variantId> --place <name> [--notes=...] [--start-date=YYYY-MM-DD] [--end-date=YYYY-MM-DD] [--return-to-home]` | Add a destination. |
| `mna destinations edit <tripId> <variantId> <destinationKey> [--place=...] [--notes=...] [--start-date=YYYY-MM-DD] [--end-date=YYYY-MM-DD] [--no-return-to-home]` | Update destination. |
| `mna destinations reorder <tripId> <variantId> --order=key1,key2,key3` | Reorder destinations. |
| `mna destinations delete <tripId> <variantId> <destinationKey> [--yes]` | Delete a destination. |

### Options (accommodation \| transport \| getting-around)

| Command | Description |
|---|---|
| `mna options add <tripId> <variantId> <destinationKey> <kind> --from-json=<file>` | Add an option from JSON. |
| `mna options edit <tripId> <variantId> <destinationKey> <kind> <optionKey> --from-json=<file>` | Edit an option. |
| `mna options add <tripId> <variantId> <destinationKey> <kind> --from-json=<file> [--free-cancellation-until=<date>]` | Add an option from JSON. `--free-cancellation-until` (accommodation only) merges into the body. |
| `mna options edit <tripId> <variantId> <destinationKey> <kind> <optionKey> [--from-json=<file>] [--free-cancellation-until=<date>]` | Edit an option. For accommodation, `--free-cancellation-until` alone updates the date without a JSON file. |
| `mna options delete <tripId> <variantId> <destinationKey> <kind> <optionKey> [--yes]` | Delete an option. |
| `mna options select <tripId> <variantId> <destinationKey> <kind> <optionKey>` | Select an option. |
| `mna options deselect <tripId> <variantId> <destinationKey> <kind>` | Deselect the current option. |
Expand Down
275 changes: 272 additions & 3 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,14 @@
},
"responses": {
"201": {
"description": "Option created."
"description": "Option created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateOptionResultV1Dto"
}
}
}
}
},
"tags": [
Expand Down Expand Up @@ -294,7 +301,14 @@
},
"responses": {
"201": {
"description": "Option created."
"description": "Option created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateOptionResultV1Dto"
}
}
}
}
},
"tags": [
Expand Down Expand Up @@ -349,7 +363,14 @@
},
"responses": {
"201": {
"description": "Option created."
"description": "Option created.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateOptionResultV1Dto"
}
}
}
}
},
"tags": [
Expand Down Expand Up @@ -1030,6 +1051,27 @@
}
}
],
"requestBody": {
"required": true,
"description": "Fields to update. The shape depends on the :kind path segment.",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/UpdateAccommodationOptionV1Dto"
},
{
"$ref": "#/components/schemas/UpdateTransportOptionV1Dto"
},
{
"$ref": "#/components/schemas/UpdateGettingAroundOptionV1Dto"
}
]
}
}
}
},
"responses": {
"200": {
"description": "Option updated."
Expand Down Expand Up @@ -2952,6 +2994,10 @@
"type": "string",
"format": "date-time"
},
"freeCancellationUntil": {
"type": "string",
"format": "date-time"
},
"checkInTime": {
"type": "string"
},
Expand Down Expand Up @@ -3100,6 +3146,16 @@
"isReturnToHome": {
"type": "boolean"
},
"startDate": {
"type": "string",
"format": "date-time",
"description": "Arrival date at this destination."
},
"endDate": {
"type": "string",
"format": "date-time",
"description": "Departure date from this destination."
},
"accommodationOptions": {
"type": "array",
"items": {
Expand Down Expand Up @@ -3411,6 +3467,29 @@
"location": {
"$ref": "#/components/schemas/CreateOptionLocationV1Dto"
},
"checkIn": {
"type": "string",
"format": "date-time",
"description": "Check-in date."
},
"checkOut": {
"type": "string",
"format": "date-time",
"description": "Check-out date."
},
"checkInTime": {
"type": "string",
"description": "Check-in time of day (e.g. \"15:00\")."
},
"checkOutTime": {
"type": "string",
"description": "Check-out time of day (e.g. \"11:00\")."
},
"freeCancellationUntil": {
"type": "string",
"format": "date-time",
"description": "Free cancellation deadline."
},
"roomDetails": {
"$ref": "#/components/schemas/RoomDetailsV1Dto"
},
Expand All @@ -3430,6 +3509,18 @@
"roomDetails"
]
},
"CreateOptionResultV1Dto": {
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "Server-assigned key for the newly-created option."
}
},
"required": [
"key"
]
},
"CreateTransportOptionV1Dto": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -3788,6 +3879,16 @@
"type": "boolean",
"description": "Marks this destination as the return-to-home leg. Server keeps it pinned to the end."
},
"startDate": {
"type": "string",
"format": "date-time",
"description": "Arrival date at this destination."
},
"endDate": {
"type": "string",
"format": "date-time",
"description": "Departure date from this destination."
},
"notes": {
"type": "string",
"description": "Free-form destination notes."
Expand Down Expand Up @@ -3820,6 +3921,16 @@
"type": "boolean",
"description": "Toggle return-to-home semantics."
},
"startDate": {
"type": "string",
"format": "date-time",
"description": "Arrival date at this destination. Pass null to clear."
},
"endDate": {
"type": "string",
"format": "date-time",
"description": "Departure date from this destination. Pass null to clear."
},
"notes": {
"type": "string",
"description": "New free-form notes."
Expand Down Expand Up @@ -3857,6 +3968,164 @@
"destinationKey"
]
},
"UpdateAccommodationOptionV1Dto": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the accommodation."
},
"type": {
"type": "string",
"enum": [
"hotel",
"hostel",
"apartment",
"house",
"camping",
"other"
],
"description": "Type of accommodation."
},
"totalCost": {
"type": "number",
"description": "Total cost for the stay."
},
"currency": {
"type": "string",
"description": "Currency code (e.g. \"USD\")."
},
"location": {
"$ref": "#/components/schemas/CreateOptionLocationV1Dto"
},
"checkIn": {
"type": "string",
"format": "date-time",
"description": "Check-in date."
},
"checkOut": {
"type": "string",
"format": "date-time",
"description": "Check-out date."
},
"checkInTime": {
"type": "string",
"description": "Check-in time of day (e.g. \"15:00\")."
},
"checkOutTime": {
"type": "string",
"description": "Check-out time of day (e.g. \"11:00\")."
},
"freeCancellationUntil": {
"type": "string",
"format": "date-time",
"description": "Free cancellation deadline. Pass null to clear."
},
"roomDetails": {
"$ref": "#/components/schemas/RoomDetailsV1Dto"
},
"notes": {
"type": "string"
},
"sourceUrl": {
"type": "string"
}
}
},
"UpdateTransportOptionV1Dto": {
"type": "object",
"properties": {
"totalCost": {
"type": "number"
},
"currency": {
"type": "string"
},
"from": {
"$ref": "#/components/schemas/CreateOptionLocationV1Dto"
},
"to": {
"$ref": "#/components/schemas/CreateOptionLocationV1Dto"
},
"departAt": {
"type": "string",
"format": "date-time"
},
"arriveAt": {
"type": "string",
"format": "date-time"
},
"durationHours": {
"type": "number"
},
"durationMinutes": {
"type": "number"
},
"transportType": {
"type": "string",
"enum": [
"car",
"plane",
"train",
"bus",
"ship",
"motorbike",
"bike",
"other"
]
},
"roundTrip": {
"type": "boolean"
},
"outboundIncludesReturnCost": {
"type": "boolean"
},
"roundTripReturn": {
"type": "boolean"
},
"returnTransportOptionKey": {
"type": "string"
},
"notes": {
"type": "string"
},
"link": {
"type": "string"
}
}
},
"UpdateGettingAroundOptionV1Dto": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"walk",
"publicTransport",
"rideShare",
"ownCar",
"rentalCar",
"ownMotor",
"rentalMotor",
"bike",
"rentalBike",
"other"
]
},
"totalCost": {
"type": "number"
},
"currency": {
"type": "string"
},
"notes": {
"type": "string"
},
"link": {
"type": "string"
}
}
},
"DeleteOptionResultV1Dto": {
"type": "object",
"properties": {
Expand Down
Loading
Loading