Please read and follow our Code of Conduct before contributing.
- Use Node.js 22 or newer.
- Install dependencies with
npm install. - Run
npm run devfor local work. - Run
npm run checkbefore opening a pull request. - Use an editor with native EditorConfig support or install its EditorConfig extension so indentation, UTF-8 encoding, LF endings, and final newlines match the repository defaults.
- Keep route files in
src/appfocused on composition and metadata. - Put reusable route-shell primitives in
src/components/scaffold. - Put shared scaffold helpers in
src/features/scaffold. - Put shared typed configuration in
src/config. - Preserve TypeScript strictness and avoid
anyunless there is a clear reason. - Treat the default UI as a placeholder shell. New product UI should come from tracked issues and approved Figma work.
- Create a branch for your work.
- Link the work to an issue when possible. If a task does not exist yet, open one with the closest template.
- Keep the change scoped to a single concern where practical.
- Avoid speculative UI or product flows that are not requested by the issue.
- Build from the approved Figma scope for that route or section, not from removed placeholder content.
- Update docs when behavior, contributor workflow, or repo expectations change.
- Validate the branch locally before asking for review.
Routes are registered centrally so that their metadata, scaffold page, route types,
and sitemap behavior stay in sync. The following minimal example shows how the
static dashboard route /app/developers is wired:
-
Add the path to
StaticSiteRouteinsrc/types/site.ts. If the new path has a dynamic segment (for example,/app/agents/[id]), add it toDynamicSiteRouteinstead.SiteRouteis defined as the union of those two types, so it includes the new path without another literal entry. -
Add a
RouteScaffoldentry torouteScaffoldsinsrc/config/routes.ts. Give it a uniqueid, assign the appropriatesection, and document its purpose, Figma scope, and implementation areas. Decide whether the route belongs in the generated sitemap: setincludeInSitemap: truefor public, indexable static pages andfalsefor authenticated, private, or dynamic pages. ThestaticSitePagesfilter uses this flag, sosrc/app/sitemap.tsdoes not need a separate route entry.{ id: "developers", title: "Developer Console", path: "/app/developers", section: "dashboard", purpose: "Provide developer-specific tooling and references.", figmaScope: "Translate the approved developer workspace from Figma.", implementationAreas: ["Console navigation", "API and SDK tooling"], includeInSitemap: false, }
-
Create the matching App Router page at
src/app/app/developers/page.tsx(route groups such as(marketing)may also be used where appropriate). Keep the route file as a small wrapper around the shared scaffold factory, passing the registryid:import { createScaffoldPage } from "@/features/scaffold/page-factory"; export default createScaffoldPage("developers");
-
Update
src/config/routes.test.ts. Increment therouteScaffoldstoHaveLength(...)assertion for every registry entry added, and add focused assertions when the route introduces new sitemap or section behavior. -
Run the validation commands below. Type checking catches paths missing from the route unions, while the route tests catch registry count and sitemap regressions.
In summary, every new route changes src/types/site.ts,
src/config/routes.ts, its page under src/app, and
src/config/routes.test.ts. Sitemap membership is controlled by
includeInSitemap in the registry; only change src/app/sitemap.ts if the
sitemap generation logic itself needs to change.
Run these commands before opening a pull request:
node scripts/add-route.mjsThe script will:
- Prompt for route ID, title, path, section, and purpose
- Generate the page file content using
createScaffoldPageandcreateScaffoldMetadata - Print the registry entry to add to
src/config/routes.ts - Print the type union update needed for
src/types/site.ts - Optionally write the page file to the correct directory
CI also runs npm audit --omit=dev --audit-level=high after installing from package-lock.json. The audit job fails only on high-severity advisories in production dependencies; dev-only advisories are excluded via --omit=dev.
When the dependency audit job fails locally or in CI:
- Reproduce with
npm cithennpm audit --omit=dev --audit-level=highso results match CI (do not usenpm install, which can drift from the lockfile). - Identify whether each advisory affects a direct dependency or a transitive one (
npm auditlists the dependency chain). - Prefer upgrading to a patched release within the project's supported range. Use Dependabot PRs when they exist, or bump
package.jsonand regenerate the lockfile withnpm install <package>@<version>. - If no fix is available yet, assess exploitability in this app (server vs client, dev-only tooling vs production runtime). Document the risk and link the advisory in the PR; do not merge with a failing audit unless maintainers explicitly accept the exception.
- Do not use
npm audit fix --forcewithout review—it can jump to major versions outside the stated dependency range.
- Add the printed registry entry to
routeScaffoldsinsrc/config/routes.ts - Update
StaticSiteRouteinsrc/types/site.tsif adding a static route - Update the route count assertion in
src/config/routes.test.tsif applicable - Implement the real UI from Figma in the generated page file
npm install
npm run dev- Pass loading, empty, and completion messages through the
PageScaffoldstatusMessageprop so assistive technology receives polite announcements. - Do not render an empty live region before a page has a meaningful status to announce.
- Read the issue labels and triage guide to understand what each label means, how issues become ready for work, and how assignment works.
- Use the bug report template for regressions and broken behavior.
- Use the feature request template for roadmap or product ideas.
- Use the contributor task template to define scoped implementation work that external contributors can pick up quickly.
- Reviewers will prioritize correctness, maintainability, and contributor clarity.
- Small PRs move faster than wide refactors, so prefer incremental improvements when possible.
- If a decision has non-obvious tradeoffs, document it in the PR instead of relying on review comments to provide context.
All contributors are expected to follow the Code of Conduct. Report conduct concerns privately through the Lily Protocol contact channel listed on the project website or GitHub organization profile rather than opening a public issue.
Use the GitHub issue templates for bugs, features, and contributor-scoped tasks. Reproduction steps, expected behavior, acceptance criteria, and screenshots help us move faster.
Please review and adhere to our Code of Conduct in all project spaces and discussions.