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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Aligned CLI flag types, values and validation with what the public API actually accepts: `codes --max-redemptions 0` / `--expire-after 0` now send `null` (unlimited / clear) rather than 422; `maps paths --cost` is an integer and `--cost-override` a boolean; `maps paths --direction` accepts `bidirectional | forward | backward`; `maps layers features create` requires `--name`; `collections items --radius` is guarded `>= 1`; `screens sections prices`/`hours` honour `--lang` for their translated fields; `CrossRegionLink` is rejected client-side for collection-item and link-item types; media types validate through one shared `api.ValidateMediaType`; and `codes list --sort-field` no longer advertises the unsupported `redemptions`.
- Corrected MCP tool contracts: `list_collection_items` returns its rows under a `collection_items` key (was a generic `items`); `create_collection`/`screen`/`section`/`code`/`media`/`map_feature` document their server-required fields; pagination params are described consistently (server default 30, max 1000) instead of four contradictory phrasings; `delete_media` gained a per-locale `language` arg; and `update_collection`/`update_screen` note the `primary_language`-flip caveat.
- Fixed inaccurate skill reference and workflow docs: dropped the non-existent `exhibit` collection type and the "codes link to screens" claim, resolved the self-contradictory `--lang`-on-reads note, corrected the `maps path-nodes`/`paths` flag signatures, documented the `0 = unlimited` code sentinel and the `--radius >= 1` minimum, and quoted the real opening-time sub-item 422 message.

## [0.10.33] - 2026-05-28

Expand Down
80 changes: 70 additions & 10 deletions internal/skills/stqry-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ Top-level entities (all exist independently):
Screens
└── Sections
└── Sub-items (hours, links, badges, prices, social, media)
Quizzes
└── Questions (position-ordered)
└── Answers (position-ordered)
Media Items
Uploaded Files (the binaries Media Items reference)
Codes
Expand All @@ -79,12 +82,13 @@ Collections are composed via Collection Items (join records):
**Collection Items are join records**, not content containers. A collection item has two fields: `item_type` (`"Screen"` or `"Collection"`) and `item_id` (the ID of the referenced entity). The referenced entity must exist before the collection item is created — create screens first, then link them into collections.

- **Projects** — top-level organisational units; each project belongs to one STQRY account.
- **Collections** — groupings of screens or other collections. Each collection has a type (tour, exhibit, etc.).
- **Collections** — groupings of screens or other collections. Each collection has a type: one of `list`, `tour`, `organization`, `menu`, `search`.
- **Screens** — standalone content pages. A screen has sections and can be linked into one or more collections.
- **Sections** — content blocks within a screen (text, image, audio, video, etc.).
- **Sub-items** — structured data attached to a section: hours, links, badges, prices, social handles, media.
- **Quizzes** — interactive quizzes. A quiz has questions; each question has answers. A quiz is surfaced in an app by a `quiz_question` / `quiz_score` story section on a screen.
- **Media Items** — images, audio, video, and documents. Can be uploaded and attached independently.
- **Codes** — redemption codes that deep-link into collections or screens.
- **Codes** — redemption codes that deep-link into a collection or a whole project (`--linked-type Collection | Project`). (Not individual screens — the public API's `linked_type` enum is `Collection` / `Project`.)

---

Expand Down Expand Up @@ -270,9 +274,9 @@ done

### Language Support

- When `--lang` is omitted, **writes** use the account's `settings.default_content_language` (looked up once per CLI invocation via `GET /api/public/account` and cached). On older API servers that don't expose `/api/public/account`, the CLI silently falls back to `en`. **Reads** that take an optional `language` query param (e.g. `stqry media list`, `stqry media get`) leave it unset when `--lang` is omitted, letting the API return its default representation.
- Pass `--lang <code>` to override the account default for a single command.
- `get` subcommands always return the full translation map for every translated field; `--lang` on a `get` has no effect and prints a stderr warning to surface the misuse. To extract a single locale's value, pipe through `--jq` (e.g. `stqry screens get 1 --jq '.title.en'`).
- When `--lang` is omitted, **writes** (create / update, and `media upload`) use the account's `settings.default_content_language` (looked up once per CLI invocation via `GET /api/public/account` and cached). On older API servers that don't expose `/api/public/account`, the CLI silently falls back to `en`.
- Pass `--lang <code>` to override the account default for a single command — it sets the locale key under which translated fields are written.
- **Reads** (`get`, `list`, `appears-in`) always return the full translation map for every translated field — no read endpoint takes a `language` query param, so `--lang` on a read has no effect and prints a stderr warning to surface the misuse. To extract a single locale's value, pipe through `--jq` (e.g. `stqry screens get 1 --jq '.title.en'`).
- Language codes follow IETF BCP 47 (e.g. `en`, `fr`, `de`, `zh-Hans`); validated client-side against the canonical list (`stqry config languages`).

---
Expand Down Expand Up @@ -340,7 +344,7 @@ stqry collections appears-in <id> Show every place this collection
stqry collections items list <collection-id> List items in a collection
stqry collections items get <collection-id> <item-id> Get a single collection item
stqry collections items add <collection-id> --item-type <type> --item-id <id> [--position <n>] Add a screen or collection to a collection
stqry collections items update <collection-id> <item-id> [--position <n>] [--lat <l>] [--lng <l>] [--item-number <s>] [--geofence <mode>] [--radius <m>] [--geofence-lat <l>] [--geofence-lng <l>] [--geofence-content] Update a single collection item (position, GPS pin, geofence). --radius merges into gps_settings so existing geofence_lat / geofence_lng aren't clobbered. Bulk with a shell loop — see the geofence snippet below.
stqry collections items update <collection-id> <item-id> [--position <n>] [--lat <l>] [--lng <l>] [--item-number <n>] [--geofence <mode>] [--radius <m>] [--geofence-lat <l>] [--geofence-lng <l>] [--geofence-content] Update a single collection item (position, GPS pin, geofence). --radius merges into gps_settings so existing geofence_lat / geofence_lng aren't clobbered. Bulk with a shell loop — see the geofence snippet below.
stqry collections items reorder <collection-id> <item-id>... Reorder items in a collection (positions applied to the whole list; the bulk-reorder endpoint is 1-based — the singular `--position` flag on `add`/`update` is 0-based)
stqry collections items remove <collection-id> <item-id> Remove an item from a collection
```
Expand Down Expand Up @@ -394,7 +398,62 @@ stqry screens sections social list|add|update|remove --screen-id <id> --sectio
stqry screens sections hours list|add|update|remove --screen-id <id> --section-id <id>
```

**Link items.** The `--link-type` enum is the full set `twitter, whatsapp, wechat, facebook, instagram, pinterest, youtube, vimeo, linkedin, tiktok, weibo, bluesky, internal, url, email, phone, live_tours, settings, badges, favourites, download, app_rating, search`. For a URL link use `--link-type url --url <destination> --link-text <label>`; for a social handle use `--link-type <network> --username <handle> --link-text <label>` (the URL is derived server-side from the handle). For a link pointing at another piece of STQRY content use `--link-type internal --item-type <Screen|Collection|CollectionItem|MediaItem|Bundle|CrossRegionLink> --item-id <id>`. The icon is auto-chosen from `--link-type` (globe for `url`, the network's logo for social types, etc.) — there is no way to pick among stock icons. `--icon-type clear` hides the icon; `media_item` is an internal Builder mode and isn't configurable from this CLI. All link-text / url / username fields are TranslatedString and respect `--lang`.
**Link items.** The `--link-type` enum is the full set `twitter, whatsapp, wechat, facebook, instagram, pinterest, youtube, vimeo, linkedin, tiktok, weibo, bluesky, internal, url, email, phone, live_tours, settings, badges, favourites, download, app_rating, search`. For a URL link use `--link-type url --url <destination> --link-text <label>`; for a social handle use `--link-type <network> --username <handle> --link-text <label>` (the URL is derived server-side from the handle). For a link pointing at another piece of STQRY content use `--link-type internal --item-type <Screen|Collection|CollectionItem|MediaItem|Bundle> --item-id <id>`. The icon is auto-chosen from `--link-type` (globe for `url`, the network's logo for social types, etc.) — there is no way to pick among stock icons. `--icon-type clear` hides the icon; `media_item` is an internal Builder mode and isn't configurable from this CLI. All link-text / url / username fields are TranslatedString and respect `--lang`.

---

### `stqry quizzes`

Manage quizzes, their questions, and each question's answers — a three-level hierarchy. A quiz is surfaced in an app by a `quiz_question` / `quiz_score` story section on a screen; use `stqry quizzes appears-in <id>` to find the screens that embed it.

```
stqry quizzes list List quizzes
stqry quizzes get <id> Get a single quiz
stqry quizzes create [--name <n>] [--title <t>] [--short-title <t>] [--primary-language <code>] Create a quiz (--name or --title required). `name` is a flat label, `title` / `short_title` are translatable. --title defaults to --name, --short-title defaults to --title; --primary-language defaults to the resolved content language.
stqry quizzes update <id> [--name <n>] [--title <t>] [--short-title <t>] [--primary-language <code>] Update a quiz. --primary-language flips the primary locale (the target locale must already have title + short_title populated, or the flip is rejected); existing translations are preserved.
stqry quizzes delete <id> [--lang <code>] Delete a quiz entirely, or only one locale's translations with --lang.
stqry quizzes appears-in <id> Show the screens that reference this quiz (via a quiz_question / quiz_score story section).
```

#### `stqry quizzes questions`

Questions belong to a quiz and are position-ordered. Pass the parent `<quiz-id>` positionally (like `collections items`).

```
stqry quizzes questions list <quiz-id> [--q <search>] List questions for a quiz
stqry quizzes questions get <quiz-id> <question-id> Get a single question
stqry quizzes questions add <quiz-id> --name <n> --question-type <t> [--question <p>] [--correct-text <s>] [--incorrect-text <s>] [--title <t>] [--max-attempts <n>] [--position <n>] [--correct-image-media-item-id <n>] [--incorrect-image-media-item-id <n>] [--correct-audio-media-item-id <n>] [--incorrect-audio-media-item-id <n>] Add a question. --name and --question-type are required client-side; the server also requires title, question, correct_text and incorrect_text on the primary language (--title defaults to --name; pass the other three).
stqry quizzes questions update <quiz-id> <question-id> [...same flags...] Update a question (any subset of the add flags)
stqry quizzes questions remove <quiz-id> <question-id> [--lang <code>] Remove a question entirely, or drop only one locale's translations with --lang.
stqry quizzes questions reorder <quiz-id> <question-id>... Reorder questions (IDs in desired order; first becomes position 0)
stqry quizzes questions appears-in <quiz-id> <question-id> Show references to a question (screens, parent quiz, badges)
```

`--question-type` is one of: `single_text_choice`, `single_image_choice`, `multi_text_choice`, `multi_image_choice`, `free_text`. The `*_image_choice` types are "image questions" (their answers carry an image media item via `--answer-media-item-id`); the rest are "text questions" (their answers carry `--answer-text`). The four question-level media flags are optional correct/incorrect feedback image/audio shown after answering; each must reference a media item of the matching subtype (image vs audio) or the server returns 422. Cross-account media item ids are silently dropped.

#### `stqry quizzes questions answers`

Answers belong to a question and are position-ordered. Pass both parents positionally: `<quiz-id>` then `<question-id>`.

```
stqry quizzes questions answers list <quiz-id> <question-id> [--q <search>] List answers for a question
stqry quizzes questions answers get <quiz-id> <question-id> <answer-id> Get a single answer
stqry quizzes questions answers add <quiz-id> <question-id> [--answer-text <s>] [--correct] [--answer-media-item-id <n>] [--position <n>] Add an answer. Text questions need --answer-text; image questions need --answer-media-item-id (an image media item). Mark the right answer(s) with --correct (default: false).
stqry quizzes questions answers update <quiz-id> <question-id> <answer-id> [--answer-text <s>] [--correct[=false]] [--answer-media-item-id <n>] [--position <n>] Update an answer. Pass --correct=false to mark an answer incorrect.
stqry quizzes questions answers remove <quiz-id> <question-id> <answer-id> [--lang <code>] Remove an answer entirely, or drop only one locale's translations with --lang.
stqry quizzes questions answers reorder <quiz-id> <question-id> <answer-id>... Reorder answers (IDs in desired order; first becomes position 0)
stqry quizzes questions answers appears-in <quiz-id> <question-id> <answer-id> Show references to an answer (parent quiz, screens)
```

**Reorder positions are 0-based here** (the first id becomes position 0), unlike the 1-based `collections items reorder`. End-to-end build example:

```bash
quiz=$(stqry quizzes create --name "Capitals Quiz" --jq '.id')
q=$(stqry quizzes questions add "$quiz" --name "Q1" --question-type single_text_choice \
--question "Capital of France?" --correct-text "Correct!" --incorrect-text "Try again" --jq '.id')
stqry quizzes questions answers add "$quiz" "$q" --answer-text "Paris" --correct
stqry quizzes questions answers add "$quiz" "$q" --answer-text "Lyon"
```

---

Expand Down Expand Up @@ -537,9 +596,10 @@ stqry maps layers features list|get|create|update|delete --map-id <id> --layer-i

stqry maps pois list|get|create|update|delete --map-id <id> [--name <n>] [--title <t>] [--item-type <Collection|Screen>] [--item-id <n>] ...
Map points-of-interest. --item-type lets a POI link to a Collection or Screen.
stqry maps path-nodes list|get|create|update|delete --map-id <id> [--lat <l>] [--lng <l>] [--layer-id <id>] [--accessible]
Nodes used by paths for routing / find-path.
stqry maps paths list|get|create|update|delete --map-id <id> --start-node-id <n> --end-node-id <n> [--cost <f>] [--accessible]
stqry maps path-nodes list|get|create|update|delete --map-id <id> --map-layer-id <id> --lat <l> --lng <l> [--map-feature-ids <csv>]
Nodes used by paths for routing / find-path. (`accessible` lives on the
path edges, not the nodes — there is no node-level accessible flag.)
stqry maps paths list|get|create|update|delete --map-id <id> --start-node-id <n> --end-node-id <n> [--cost <n>] [--cost-override] [--accessible] [--direction <d>] [--linestring-json <json>]
Paths between two nodes (cost-weighted edges in the routing graph).
stqry maps paths split --map-id <id> <id> --node-id <n> Split a path at an intermediate node
```
Expand Down
2 changes: 1 addition & 1 deletion internal/skills/stqry-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ stqry screens sections media add \

## Workflow 3: Set Up a Screen with Story Sections and Sub-items

This builds a rich screen with opening hours, external links, and image badges. **Sub-items live on a section whose `--type` matches their kind** — hours go on an `opening_time_group`, links on a `link_group`, badges on a `badge_group`. There is no "everything on one text section" — attaching `hours add` to a `text` section returns `422 Story section must be an opening_time_group` server-side. So this workflow creates one section per sub-item kind, plus the text intro.
This builds a rich screen with opening hours, external links, and image badges. **Sub-items live on a section whose `--type` matches their kind** — hours go on an `opening_time_group`, links on a `link_group`, badges on a `badge_group`. There is no "everything on one text section" — attaching `hours add` to a `text` section returns `422 Story section must be a opening time group` server-side (quoted verbatim — the grammatically-odd wording is the real server message). So this workflow creates one section per sub-item kind, plus the text intro.

### Step 1 — Create the screen

Expand Down
Loading