{"id":49539530,"url":"https://github.com/ankhorage/templates","last_synced_at":"2026-06-04T22:00:42.073Z","repository":{"id":355211950,"uuid":"1214942316","full_name":"ankhorage/templates","owner":"ankhorage","description":"App templates and manifest generators for Ankhorage — ZORA-based project scaffolds built on @ankhorage/surface.","archived":false,"fork":false,"pushed_at":"2026-06-02T03:34:51.000Z","size":504,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-02T04:16:46.932Z","etag":null,"topics":["ankhorage","app-template","code-generator","cross-platform","design-system","design-tokens","expo","project-template","react-native","react-native-web","scaffolding","templates","typescript","ui-kit","zora"],"latest_commit_sha":null,"homepage":"https://ankhorage.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ankhorage.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-19T09:03:39.000Z","updated_at":"2026-06-02T03:30:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ankhorage/templates","commit_stats":null,"previous_names":["ankhorage/templates"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/ankhorage/templates","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankhorage%2Ftemplates","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankhorage%2Ftemplates/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankhorage%2Ftemplates/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankhorage%2Ftemplates/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ankhorage","download_url":"https://codeload.github.com/ankhorage/templates/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankhorage%2Ftemplates/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33921352,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ankhorage","app-template","code-generator","cross-platform","design-system","design-tokens","expo","project-template","react-native","react-native-web","scaffolding","templates","typescript","ui-kit","zora"],"created_at":"2026-05-02T14:00:47.632Z","updated_at":"2026-06-04T22:00:42.028Z","avatar_url":"https://github.com/ankhorage.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @ankhorage/templates\n\nReusable Ankhorage app templates, presets, and manifest generators.\n\n## Usage\n\n```ts\nimport {\n  createCategoryAppManifest,\n  createStarterTemplate,\n  listStarterTemplatesByCategory,\n} from '@ankhorage/templates';\n\nconst manifest = createCategoryAppManifest('social_community');\n\nconst creatorManifest = createStarterTemplate(seed, {\n  templateId: 'creator',\n});\n\nconst gameTemplates = listStarterTemplatesByCategory('games');\n```\n\n## Category Starter Templates\n\nStarter templates are category-aware. A category can expose one or more template variants.\nFor example, `social_community` provides a default community starter and a `creator`\nstarter, while `games` provides the default quest-loop starter and a `chess` starter.\n\nUse `listStarterTemplatesByCategory(category)` when an editor or generator needs a selectable\nlist for one category. It returns summaries only, not factories:\n\n```ts\nconst templates = listStarterTemplatesByCategory('games');\n// [\n//   { id: 'default', category: 'games', label: 'Quest loop', ... },\n//   { id: 'chess', category: 'games', label: 'Chess', ... },\n// ]\n```\n\nUse `listStarterTemplateSummaries()` when a tool needs all registered starter choices.\n\nDefault resolution is deterministic:\n\n- no `templateId` selects `default`\n- an unknown template id falls back to that category's `default`\n- an unregistered category falls back to `fallback/default`\n\nThe generated manifest includes category-specific routes, screens, copy, and route icons.\nIcons use the existing route `icon: IconSpec` property from `@ankhorage/contracts`:\n\n```ts\n{\n  name: 'groups',\n  screenId: 'social_community-community-starter-groups',\n  label: 'Groups',\n  icon: { provider: 'material-community', name: 'account-group-outline' },\n}\n```\n\nAuth behavior is not modeled as a visible navigation route in category templates. It remains\ncontrolled by the manifest `infra` and `settings.authFlow` configuration. The original generic\nstarter remains available as the fallback template and preserves its existing sign-in screen.\n\n## Current Templates\n\nAll `AppCategory` values have a dedicated `starter/default` template with an explicit\n`navigator.type`, deterministic route labels, and `material-community` route icons.\n\n| Category                | Navigator | Routes (labels)                                                        | Icons (`material-community`)                                                                                                                      |\n| ----------------------- | --------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `books_reading`         | `tabs`    | Library · Discover · Lists · Notes · Profile                           | `bookshelf` · `compass-outline` · `format-list-checks` · `notebook-outline` · `account-circle-outline`                                            |\n| `business_productivity` | `drawer`  | Dashboard · Projects · Tasks · Calendar · Reports · Settings           | `view-dashboard-outline` · `folder-multiple-outline` · `clipboard-check-outline` · `calendar-month-outline` · `chart-box-outline` · `cog-outline` |\n| `developer_tools`       | `drawer`  | Dashboard · Builds · Incidents · Environments · Deployments · Settings | `view-dashboard-outline` · `hammer-wrench` · `alert-circle-outline` · `server-network` · `rocket-launch-outline` · `cog-outline`                  |\n| `education_learning`    | `tabs`    | Courses · Study · Practice · Progress · Profile                        | `book-education-outline` · `school-outline` · `pencil-box-outline` · `chart-line` · `account-circle-outline`                                      |\n| `entertainment_media`   | `tabs`    | Discover · Watchlist · Now · Library · Profile                         | `compass-outline` · `bookmark-outline` · `play-circle-outline` · `movie-open-outline` · `account-circle-outline`                                  |\n| `finance_money`         | `tabs`    | Overview · Accounts · Transactions · Budget · Insights                 | `view-dashboard-outline` · `bank-outline` · `swap-horizontal` · `wallet-outline` · `chart-donut`                                                  |\n| `food_drink`            | `tabs`    | Discover · Menu · Reservations · Orders · Profile                      | `silverware-fork-knife` · `book-open-page-variant-outline` · `calendar-clock-outline` · `receipt-text-outline` · `account-heart-outline`          |\n| `games`                 | `tabs`    | Home · Quests · Inventory · Friends · Profile                          | `gamepad-variant-outline` · `flag-outline` · `treasure-chest-outline` · `account-multiple-outline` · `account-circle-outline`                     |\n| `graphics_design`       | `drawer`  | Dashboard · Briefs · Assets · Reviews · Brand · Settings               | `view-dashboard-outline` · `file-document-outline` · `image-multiple-outline` · `comment-check-outline` · `palette-outline` · `cog-outline`       |\n| `health_fitness`        | `tabs`    | Today · Plans · Progress · Coach · Profile                             | `calendar-today-outline` · `clipboard-list-outline` · `chart-line` · `message-processing-outline` · `account-circle-outline`                      |\n| `kids_family`           | `tabs`    | Home · Routines · Discover · Favorites · Parents                       | `home-outline` · `calendar-check-outline` · `compass-outline` · `heart-outline` · `shield-account-outline`                                        |\n| `lifestyle`             | `tabs`    | Dashboard · Collections · Plans · Explore · Profile                    | `view-dashboard-outline` · `bookmark-multiple-outline` · `calendar-star` · `compass-outline` · `account-circle-outline`                           |\n| `medical`               | `tabs`    | Appointments · Care Team · Records · Messages · Profile                | `calendar-check-outline` · `account-heart-outline` · `file-document-outline` · `message-processing-outline` · `account-circle-outline`            |\n| `music_audio`           | `tabs`    | Home · Search · Library · Player · Profile                             | `music-note-outline` · `magnify` · `playlist-music-outline` · `play-circle-outline` · `account-circle-outline`                                    |\n| `navigation_travel`     | `tabs`    | Destinations · Itinerary · Bookings · Map · Profile                    | `map-marker-outline` · `timeline-outline` · `ticket-outline` · `map-outline` · `account-circle-outline`                                           |\n| `news_magazines`        | `tabs`    | Headlines · Topics · Saved · Search · Profile                          | `newspaper-variant-outline` · `tag-multiple-outline` · `bookmark-outline` · `magnify` · `account-circle-outline`                                  |\n| `photo_video`           | `tabs`    | Capture · Library · Edit · Share · Profile                             | `camera-outline` · `image-multiple-outline` · `movie-edit-outline` · `share-variant-outline` · `account-circle-outline`                           |\n| `reference`             | `drawer`  | Browse · Search · Categories · Saved · History · Settings              | `book-open-variant` · `magnify` · `shape-outline` · `bookmark-outline` · `clock-outline` · `cog-outline`                                          |\n| `shopping_commerce`     | `tabs`    | Browse · Search · Sell · Orders · Profile                              | `shopping-outline` · `magnify` · `store-plus-outline` · `package-variant-closed` · `account-circle-outline`                                       |\n| `social_community`      | `tabs`    | Feed · Groups · Messages · Profile · Settings                          | `newspaper-variant-outline` · `account-group-outline` · `message-text-outline` · `account-circle-outline` · `cog-outline`                         |\n| `sports`                | `tabs`    | Scores · Schedule · Standings · Teams · Profile                        | `scoreboard-outline` · `calendar-month-outline` · `format-list-numbered` · `soccer-field` · `account-circle-outline`                              |\n| `utilities_tools`       | `drawer`  | Dashboard · Tools · Shortcuts · Storage · Diagnostics · Settings       | `view-dashboard-outline` · `wrench-outline` · `lightning-bolt-outline` · `folder-multiple-outline` · `stethoscope` · `cog-outline`                |\n| `weather`               | `tabs`    | Now · Forecast · Alerts · Locations                                    | `weather-partly-cloudy` · `weather-cloudy-clock` · `weather-cloudy-alert` · `map-marker-outline`                                                  |\n\nThe fallback template remains available and is used only for unknown runtime category strings:\n\n- `fallback/default`: Home · Details · Settings (stack)\n\nAdditional variants:\n\n- `games/chess`: Home · Settings. The Home screen renders a `ChessBoard` node with a static\n  initial FEN and requires generated apps to provide `@ankhorage/zora-chess` through their\n  extension registry.\n- `food_drink/nutrition-catalog-scan`: Products · Scan · Capture · Queue · Settings. This\n  catalog-first Swiss nutrition starter expects API Gateway clients for `GET /v1/nutrition/products`,\n  `GET /v1/nutrition/products/by-barcode/{barcode}`, and `POST /v1/nutrition/products/capture`.\n  It intentionally keeps Supabase out of the generated app surface. Native barcode scanning can use\n  `expo-camera` behind an app adapter, while permission prompts, scan overlays, loading states,\n  form fields, buttons, notices, and product cards should be composed through ZORA. A reusable\n  `BarcodeScannerView` / `CameraPermissionView` belongs in ZORA once the scanner API stabilizes,\n  not in Surface.\n- `social_community/creator`: Studio · Posts · Audience · Insights · Settings\n\nOnly categories that exist in `AppCategory` are registered. New category literals should be added\nin `@ankhorage/contracts` before this package registers templates for them.\n\n## Adding A Category Template\n\nAdd category-owned files under `src/templates/starter/categories/\u003ccategory\u003e/`:\n\n- `content.ts` for category-specific copy and placeholder data\n- `routes.ts` or `routes.\u003cvariant\u003e.ts` for route names, labels, screen ids, and icons\n- `screens.ts` or `screens.\u003cvariant\u003e.ts` for ZORA node trees\n- `\u003cvariant\u003e.template.ts` for manifest assembly\n- `index.ts` for `CategoryStarterTemplateDefinition` metadata\n\nRegister the category in `src/templates/starter/starter.registry.ts`. Keep shared behavior in\n`src/templates/shared/*`; category wording and navigation should stay inside the category folder.\n\n## Verification\n\n```bash\nbun run typecheck\nbun run build\nbun run lint\nbun run test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankhorage%2Ftemplates","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fankhorage%2Ftemplates","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankhorage%2Ftemplates/lists"}