diff --git a/PLAN.md b/PLAN.md index 24ae44b..3aac953 100644 --- a/PLAN.md +++ b/PLAN.md @@ -22,7 +22,7 @@ keine Emulator-Spielerei. Das OS ist eine Metapher für Multitasking, nicht Selb ## 2. Ausgangslage (Stand heute) -Das Repo ist der unveränderte mkstack-Startpunkt: +Das Repo ist der Startpunkt für LAYER.systems: - `src/AppRouter.tsx` — drei Routen: `/`, `/:nip19`, `*` - `src/pages/` — `Index.tsx` (Platzhalter), `NIP19Page.tsx`, `NotFound.tsx` diff --git a/README.md b/README.md index 71328e7..7149e24 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ require changing the router. Read [the app guide](./docs/apps.md) before adding - [Nostr data access and safety](./docs/nostr.md) - [Style guide](./docs/styleguide.md) - [Project architecture and design decisions](./PLAN.md) +- [Versioning and release workflow](./docs/versioning.md) For protocol reference, see the [Nostr protocol documentation](https://nostr.com/). diff --git a/docs/README.md b/docs/README.md index 4332bda..cdb6fab 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,6 +11,7 @@ decisions were taken; these documents describe how it actually works. | [`apps.md`](./apps.md) | The app registry, the contract every app implements, and how to add one | | [`nostr.md`](./nostr.md) | Data access, relay hints, and the rules for rendering untrusted content | | [`styleguide.md`](./styleguide.md) | Design tokens, materials, typography, motion, and the layout rules for app content | +| [`versioning.md`](./versioning.md) | The package version source and release workflow | ## Layout of the custom code diff --git a/docs/versioning.md b/docs/versioning.md new file mode 100644 index 0000000..6de88ac --- /dev/null +++ b/docs/versioning.md @@ -0,0 +1,17 @@ +# Versioning and releases + +`package.json` is the authoritative source for the LAYER.systems package name and +semantic version. The About app imports that metadata directly, so local and +production builds display the same version. + +## Preparing a release + +1. Run `npm version patch`, `npm version minor`, or `npm version major` from the + repository root. This updates `package.json` and `package-lock.json`, creates + the matching git commit, and creates a version tag. +2. Run `npm run test` and verify the version in the About app. +3. Push the commit and tag to publish the release. + +The first tracked release is `1.0.0`. Use semantic versioning for all subsequent +releases: patch for backwards-compatible fixes, minor for backwards-compatible +features, and major for breaking changes. diff --git a/package-lock.json b/package-lock.json index 55ebf24..eb02ae5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "mkstack", - "version": "0.0.0", + "name": "LAYER.systems", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "mkstack", - "version": "0.0.0", + "name": "LAYER.systems", + "version": "1.0.0", "dependencies": { "@fontsource-variable/inter": "^5.3.0", "@nostrify/nostrify": "^0.55.1", diff --git a/package.json b/package.json index aef409f..05c1494 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "mkstack", + "name": "LAYER.systems", "private": true, - "version": "0.0.0", + "version": "1.0.0", "type": "module", "scripts": { "dev": "npm i --silent && vite", diff --git a/src/apps/about/index.test.tsx b/src/apps/about/index.test.tsx new file mode 100644 index 0000000..4f28368 --- /dev/null +++ b/src/apps/about/index.test.tsx @@ -0,0 +1,22 @@ +import { render, screen } from '@testing-library/react'; +import { describe, expect, test, vi } from 'vitest'; +import AboutApp from './index'; + +vi.mock('@/os/useWindowManager', () => ({ + useWindowManager: () => ({ openApp: vi.fn() }), +})); + +describe('About app', () => { + test('displays the package version', () => { + render( + , + ); + + expect(screen.getByText('Version 1.0.0')).toBeInTheDocument(); + }); +}); diff --git a/src/apps/about/index.tsx b/src/apps/about/index.tsx index 280e808..b5b96e9 100644 --- a/src/apps/about/index.tsx +++ b/src/apps/about/index.tsx @@ -5,6 +5,7 @@ import { Button } from '@/components/ui/button'; import { useWindowManager } from '@/os/useWindowManager'; import { APPS } from '@/os/registry'; import type { AppProps } from '@/os/types'; +import { APP_NAME, APP_VERSION } from '@/lib/appMetadata'; const SHORTCUTS: [keys: string, action: string][] = [ ['⌘K', 'Search apps and windows'], @@ -27,7 +28,8 @@ export default function AboutApp({ setTitle }: AppProps) { -

LAYER.systems

+

{APP_NAME}

+

Version {APP_VERSION}

A Nostr client shaped like a desktop. Every part of it is an app in a window you can move, resize, stack and keep open side by side — reading a thread does not diff --git a/src/lib/appMetadata.test.ts b/src/lib/appMetadata.test.ts new file mode 100644 index 0000000..69c5a95 --- /dev/null +++ b/src/lib/appMetadata.test.ts @@ -0,0 +1,12 @@ +import packageJson from '../../package.json'; +import { describe, expect, test } from 'vitest'; +import { APP_NAME, APP_VERSION } from './appMetadata'; + +describe('app metadata', () => { + test('uses package metadata as the authoritative source', () => { + expect(APP_NAME).toBe(packageJson.name); + expect(APP_VERSION).toBe(packageJson.version); + expect(APP_NAME).toBe('LAYER.systems'); + expect(APP_VERSION).toBe('1.0.0'); + }); +}); diff --git a/src/lib/appMetadata.ts b/src/lib/appMetadata.ts new file mode 100644 index 0000000..3e754d0 --- /dev/null +++ b/src/lib/appMetadata.ts @@ -0,0 +1,4 @@ +import packageJson from '../../package.json'; + +export const APP_NAME = packageJson.name; +export const APP_VERSION = packageJson.version; diff --git a/tsconfig.json b/tsconfig.json index fd4b962..8917fda 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ /* Bundler mode */ "moduleResolution": "bundler", + "resolveJsonModule": true, "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force",