chore: consume Bird from Gitea Packages

This commit is contained in:
2026-07-14 03:00:09 +09:00
parent d8827b6513
commit 6a4f7ca068
7 changed files with 58 additions and 48 deletions
+1
View File
@@ -0,0 +1 @@
@yuta:registry=https://git.yutakobayashi.com/api/packages/yuta/npm/
+3 -13
View File
@@ -22,21 +22,11 @@ they do not add related-post recommendations or an account-discovery surface.
## Requirements and setup ## Requirements and setup
Use Nix, or Node.js `>=22.12.0` with pnpm `11.9.0`. The package link also Use Nix, or Node.js `>=22.12.0` with pnpm `11.9.0`. The committed `.npmrc`
requires a local Bird checkout at `../bird`, exactly at unpublished commit routes the `@yuta` scope to the public Gitea Packages registry, where Bird
`81921226f099e7f7a2107be15fc9783218a6f400`. `0.10.0` provides the required Top and Latest search interface.
A fresh clone of the remote Bird repository alone does **not** contain that
local Top/Latest commit yet. Obtain the supplied checkout; do not assume the
commit or a compatible package has been published.
```bash ```bash
cd ../bird
git rev-parse HEAD
nix develop -c pnpm install --frozen-lockfile
nix develop -c pnpm run build:dist
cd ../twitter-lite
nix develop -c pnpm install --frozen-lockfile nix develop -c pnpm install --frozen-lockfile
cp .env.example .env.local cp .env.example .env.local
``` ```
@@ -6,11 +6,11 @@
**Architecture:** Keep Bird unchanged and compose its existing `getTweet()` and `getThreadPaged()` methods behind one new TanStack Start GET server function. The first web page resolves the focal post to its conversation root and performs two Bird reads; continuation pages carry the root ID with the opaque cursor and perform one Bird read. Reuse the established TanStack Query pagination and PostCard rendering while keeping the focal post distinct and removing duplicates from the conversation list. **Architecture:** Keep Bird unchanged and compose its existing `getTweet()` and `getThreadPaged()` methods behind one new TanStack Start GET server function. The first web page resolves the focal post to its conversation root and performs two Bird reads; continuation pages carry the root ID with the opaque cursor and perform one Bird read. Reuse the established TanStack Query pagination and PostCard rendering while keeping the focal post distinct and removing duplicates from the conversation list.
**Tech Stack:** Node.js 22, pnpm 11.9.0, TanStack Start/Router/Query, React 19, Zod 4, linked `@yuta/bird`, Vitest, Testing Library, Playwright, Nix Chromium, hand-written CSS. **Tech Stack:** Node.js 22, pnpm 11.9.0, TanStack Start/Router/Query, React 19, Zod 4, published `@yuta/bird@0.10.0`, Vitest, Testing Library, Playwright, Nix Chromium, hand-written CSS.
## Global Constraints ## Global Constraints
- Bird remains clean at `81921226f099e7f7a2107be15fc9783218a6f400`; do not edit, commit, push, or publish it. - Use the published `@yuta/[email protected]` interface; do not modify Bird as part of this feature.
- Use only Bird's existing `getTweet()` and `getThreadPaged()` methods and the existing `TweetDetail` relay operation. - Use only Bird's existing `getTweet()` and `getThreadPaged()` methods and the existing `TweetDetail` relay operation.
- Preserve the current Bird ordering: chronological within each fetched page, with cursor pages appended in retrieval order. - Preserve the current Bird ordering: chronological within each fetched page, with cursor pages appended in retrieval order.
- Do not add a dependency, database, cookie, history, recommendation, related-post feed, mutation control, generic Bird dispatcher, or generic relay proxy. - Do not add a dependency, database, cookie, history, recommendation, related-post feed, mutation control, generic Bird dispatcher, or generic relay proxy.
@@ -1668,24 +1668,23 @@ export const searchPosts = createServerFn({ method: 'GET' })
export const loadThreadPosts = createServerFn({ method: 'GET' }) export const loadThreadPosts = createServerFn({ method: 'GET' })
``` ```
- [ ] **Step 5: Verify Bird stayed unchanged and local** - [ ] **Step 5: Verify the published Bird dependency is self-contained**
Run from `../bird`: Run from Twitter Lite:
```bash ```bash
git rev-parse HEAD rg -n '"@yuta/bird": "0.10.0"' package.json
git status --short --branch rg -n '@yuta/[email protected]' pnpm-lock.yaml
git rev-list --count origin/main..HEAD rg -n 'link:../bird' package.json pnpm-lock.yaml
git log --oneline origin/main..HEAD readlink -f node_modules/@yuta/bird
``` ```
Expected: Expected:
```text ```text
81921226f099e7f7a2107be15fc9783218a6f400 package.json and pnpm-lock.yaml pin 0.10.0
## main...origin/main [ahead 1] the local-link scan has zero matches
1 node_modules resolves inside the pnpm virtual store
8192122 feat: support ranked tweet search
``` ```
- [ ] **Step 6: Perform the pre-commit documentation check** - [ ] **Step 6: Perform the pre-commit documentation check**
@@ -23,7 +23,7 @@
- Load 20 posts per cursor page and continue automatically without a fixed page limit. - Load 20 posts per cursor page and continue automatically without a fixed page limit.
- Use Mist Instrument tokens and no remote fonts; respect keyboard focus and `prefers-reduced-motion`. - Use Mist Instrument tokens and no remote fonts; respect keyboard focus and `prefers-reduced-motion`.
- Work test-first for every behavior change and run the pre-commit documentation check in both repositories. - Work test-first for every behavior change and run the pre-commit documentation check in both repositories.
- Do not push Bird or publish `@yuta/bird` without separate user authorization. - Consume the separately authorized and published `@yuta/bird@0.10.0`; do not modify Bird from the app repository.
## File Map ## File Map
@@ -385,7 +385,7 @@ git commit -m "feat: support ranked tweet search"
- Create: `tests/setup.ts` - Create: `tests/setup.ts`
**Interfaces:** **Interfaces:**
- Consumes: local `@yuta/bird` through `link:../bird`. - Consumes: published `@yuta/bird@0.10.0` through Gitea Packages.
- Produces: `getRouter()` with an SSR-aware QueryClient. - Produces: `getRouter()` with an SSR-aware QueryClient.
- Produces: a buildable TanStack Start/Nitro application at `http://127.0.0.1:3000`. - Produces: a buildable TanStack Start/Nitro application at `http://127.0.0.1:3000`.
@@ -422,6 +422,12 @@ Run `nix flake lock` to generate `flake.lock`.
- [ ] **Step 2: Add pinned package and tool configuration** - [ ] **Step 2: Add pinned package and tool configuration**
Create `.npmrc`:
```ini
@yuta:registry=https://git.yutakobayashi.com/api/packages/yuta/npm/
```
Create `package.json`: Create `package.json`:
```json ```json
@@ -451,7 +457,7 @@ Create `package.json`:
"@tanstack/react-router": "1.170.17", "@tanstack/react-router": "1.170.17",
"@tanstack/react-router-ssr-query": "1.167.1", "@tanstack/react-router-ssr-query": "1.167.1",
"@tanstack/react-start": "1.168.27", "@tanstack/react-start": "1.168.27",
"@yuta/bird": "link:../bird", "@yuta/bird": "0.10.0",
"nitro": "3.0.260610-beta", "nitro": "3.0.260610-beta",
"react": "19.2.7", "react": "19.2.7",
"react-dom": "19.2.7", "react-dom": "19.2.7",
@@ -2855,7 +2861,7 @@ git commit -m "feat: apply mist instrument interface"
- Verify: `docs/superpowers/specs/2026-07-13-twitter-lite-design.md` - Verify: `docs/superpowers/specs/2026-07-13-twitter-lite-design.md`
**Interfaces:** **Interfaces:**
- Consumes: the complete app and local Bird build. - Consumes: the complete app and published Bird package.
- Produces: deterministic desktop/mobile browser coverage and an opt-in read-only live smoke test. - Produces: deterministic desktop/mobile browser coverage and an opt-in read-only live smoke test.
- [ ] **Step 1: Add the browser configuration** - [ ] **Step 1: Add the browser configuration**
@@ -3137,17 +3143,11 @@ handle, profile URL, or search query.
## Setup ## Setup
Use Nix, or Node.js `>=22.12.0` with pnpm `11.9.0`. Obtain the supplied local Use Nix, or Node.js `>=22.12.0` with pnpm `11.9.0`. The committed `.npmrc`
Bird checkout beside this repository at unpublished commit routes `@yuta` packages to Gitea Packages, and `@yuta/bird@0.10.0` contains
`81921226f099e7f7a2107be15fc9783218a6f400`. A fresh remote clone alone does the required Top/Latest interface.
not contain that Top/Latest commit yet.
```bash ```bash
cd ../bird
git rev-parse HEAD
nix develop -c pnpm install --frozen-lockfile
nix develop -c pnpm run build:dist
cd ../twitter-lite
nix develop -c pnpm install --frozen-lockfile nix develop -c pnpm install --frozen-lockfile
``` ```
@@ -55,14 +55,12 @@ The product reduces ambient discovery rather than limiting how far a deliberate
## Repositories and Delivery Sequence ## Repositories and Delivery Sequence
Work occurs in two repositories: Work spans two repositories and the Gitea package registry:
1. Clone Bird from `https://git.yutakobayashi.com/yuta/bird` into the sibling path `../bird`. 1. Extend Bird's public search interface in `https://git.yutakobayashi.com/yuta/bird`.
2. Extend Bird's public search interface and commit the change locally. 2. Release the compatible interface as `@yuta/[email protected]` in Gitea Packages.
3. Consume the local Bird checkout from Twitter Lite with the pnpm dependency `link:../bird`. 3. Route the `@yuta` scope through the committed `.npmrc` and pin Twitter Lite to `@yuta/[email protected]`.
4. Build and verify Twitter Lite against the linked Bird package. 4. Build and verify Twitter Lite against the published package without a sibling Bird checkout.
The Bird commit is not pushed and no package is published without separate user authorization. Once a compatible Bird version is published, replacing the local link with that version is a separate maintenance task.
## Bird Library Change ## Bird Library Change
+1 -1
View File
@@ -29,7 +29,7 @@
"@tanstack/react-router": "1.170.17", "@tanstack/react-router": "1.170.17",
"@tanstack/react-router-ssr-query": "1.167.1", "@tanstack/react-router-ssr-query": "1.167.1",
"@tanstack/react-start": "1.168.27", "@tanstack/react-start": "1.168.27",
"@yuta/bird": "link:../bird", "@yuta/bird": "0.10.0",
"nitro": "3.0.260610-beta", "nitro": "3.0.260610-beta",
"react": "19.2.7", "react": "19.2.7",
"react-dom": "19.2.7", "react-dom": "19.2.7",
+24 -2
View File
@@ -21,8 +21,8 @@ importers:
specifier: 1.168.27 specifier: 1.168.27
version: 1.168.27([email protected]([email protected]))([email protected]([email protected]))([email protected])([email protected])([email protected](@types/[email protected])([email protected])) version: 1.168.27([email protected]([email protected]))([email protected]([email protected]))([email protected])([email protected])([email protected](@types/[email protected])([email protected]))
'@yuta/bird': '@yuta/bird':
specifier: link:../bird specifier: 0.10.0
version: link:../bird version: 0.10.0
nitro: nitro:
specifier: 3.0.260610-beta specifier: 3.0.260610-beta
version: 3.0.260610-beta([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected])) version: 3.0.260610-beta([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected]))
@@ -810,6 +810,10 @@ packages:
'@vitest/[email protected]': '@vitest/[email protected]':
resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==}
'@yuta/[email protected]':
resolution: {integrity: sha512-qU/zveaouKVEvEGsXxK4f1djgY7BLhi//NvyCMobEE93T+kzVFHD3wLbW9Yiz1hVqnsRIad5RtCYXeYz8gVMgg==, tarball: https://git.yutakobayashi.com/api/packages/yuta/npm/%40yuta%2Fbird/-/0.10.0/bird-0.10.0.tgz}
hasBin: true
[email protected]: [email protected]:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -878,6 +882,10 @@ packages:
[email protected]: [email protected]:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
[email protected]:
resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
engines: {node: '>=20'}
[email protected]: [email protected]:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0} engines: {node: ^14.18.0 || >=16.10.0}
@@ -1113,6 +1121,10 @@ packages:
engines: {node: '>=6'} engines: {node: '>=6'}
hasBin: true hasBin: true
[email protected]:
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
engines: {node: '>=6'}
[email protected]: [email protected]:
resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
@@ -2445,6 +2457,12 @@ snapshots:
convert-source-map: 2.0.0 convert-source-map: 2.0.0
tinyrainbow: 3.1.0 tinyrainbow: 3.1.0
'@yuta/[email protected]':
dependencies:
commander: 14.0.3
json5: 2.2.3
kleur: 4.1.5
[email protected]: {} [email protected]: {}
[email protected]: [email protected]:
@@ -2508,6 +2526,8 @@ snapshots:
[email protected]: {} [email protected]: {}
[email protected]: {}
[email protected]: {} [email protected]: {}
[email protected]: {} [email protected]: {}
@@ -2663,6 +2683,8 @@ snapshots:
[email protected]: {} [email protected]: {}
[email protected]: {}
[email protected]: [email protected]:
optional: true optional: true