@strayl/agent 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,149 +1,149 @@
1
- ---
2
- name: reference
3
- description: Essential reference for stack versions, APIs, common errors, and patterns. Read this BEFORE writing any code in a TanStack Start project to avoid wrong imports, deprecated APIs, and build errors.
4
- ---
5
-
6
- # Reference — Stack Versions & Patterns
7
-
8
- ## When to Read This Skill
9
-
10
- - **ALWAYS** before writing code that uses TanStack Start, Tailwind CSS, or shadcn/ui
11
- - Before debugging build or runtime errors
12
- - Before setting up a dev server
13
- - When unsure about correct import paths or API syntax
14
-
15
- ## Stack Versions
16
-
17
- | Package | Version | Key Changes |
18
- |---------|---------|-------------|
19
- | React | 19.x | `use()`, `useActionState()`, `useOptimistic()`, ref as prop (no forwardRef) |
20
- | TanStack Start | 1.x | `createServerFn()` with fluent API, Nitro server, config in `vite.config.ts` |
21
- | TanStack Router | 1.x | `createFileRoute()`, `Link`, `useNavigate()`, `useParams()`, `useSearch()` |
22
- | Vite | 7.x | `@tailwindcss/vite` plugin, `@tanstack/react-start/plugin/vite` |
23
- | Tailwind CSS | 4.x | CSS-based config via `@theme {}` — **NO `tailwind.config.js`** |
24
- | shadcn/ui | latest | OKLCH colors, `tw-animate-css` (NOT `tailwindcss-animate`), `@custom-variant dark` |
25
- | TypeScript | 5.7+ | strict mode |
26
-
27
- ## Tailwind CSS 4 — Critical Differences from v3
28
-
29
- - Config lives in `src/styles.css` using `@import "tailwindcss"` and `@theme {}` blocks
30
- - **NO `tailwind.config.js`** — delete it if it exists
31
- - Colors use OKLCH format, not HSL
32
- - Custom properties: `--color-primary`, `--color-background`, etc. inside `@theme inline {}`
33
- - Plugins loaded via CSS: `@plugin "..."` — NOT via JS config
34
- - No `content` array needed — auto-detection
35
- - Animation: use `tw-animate-css`, NOT `tailwindcss-animate`
36
-
37
- ## TanStack Start API
38
-
39
- ### Config
40
- Config is in `vite.config.ts` with `tanstackStart()` plugin. **NOT** old `app.config.ts` with `defineConfig`.
41
-
42
- ### Server Functions
43
- ```typescript
44
- import { createServerFn } from '@tanstack/react-start'
45
- import { z } from 'zod'
46
-
47
- const mySchema = z.object({ id: z.string() })
48
-
49
- export const getData = createServerFn({ method: 'GET' })
50
- .inputValidator((d: unknown) => mySchema.parse(d))
51
- .handler(async ({ data }) => {
52
- // data is typed as { id: string }
53
- return { result: data.id }
54
- })
55
- ```
56
-
57
- **IMPORTANT:** `.inputValidator()` takes a **FUNCTION**, not a schema directly. Always wrap zod: `.inputValidator((d: unknown) => mySchema.parse(d))`
58
-
59
- ### File-Based Routing
60
- - `$param` for dynamic segments
61
- - `_layout` prefix for pathless layouts
62
- - `__root.tsx` for root layout
63
- - Loaders: defined on route via `loader` option in `createFileRoute()`
64
-
65
- ## Common Errors & Recovery
66
-
67
- ### Build / Compile Errors
68
- | Error | Fix |
69
- |-------|-----|
70
- | `Cannot find module 'X'` | Run `npm install` first, then retry |
71
- | `Type error: ...` | Read the file, fix the type, rebuild |
72
- | `ENOENT: no such file or directory` | Check the path — likely wrong relative path |
73
-
74
- ### Dev Server Errors
75
- | Error | Fix |
76
- |-------|-----|
77
- | Port already in use | Kill the background process, restart on a different port |
78
- | `MODULE_NOT_FOUND` after install | `rm -rf node_modules && npm install` |
79
-
80
- ### Package Install Errors
81
- | Error | Fix |
82
- |-------|-----|
83
- | `ERESOLVE: peer dependency conflict` | Use `npm install --legacy-peer-deps` |
84
- | `ETARGET: no matching version` | Check the actual package name/version with `web_search` |
85
-
86
- ### Recovery Pattern
87
- 1. Read the **FULL** error message (don't guess from partial output)
88
- 2. Check `getLogs` if it was a background command
89
- 3. Fix the root cause (don't retry the same failing command)
90
- 4. **NEVER repeat the same edit or command twice** — if your fix didn't work, try a DIFFERENT approach
91
- 5. If stuck after 2 attempts, use `web_search` to find the solution
92
- 6. If still stuck, use `askUser` to explain the problem and ask for guidance
93
-
94
- ### Do NOT Loop
95
- If you edited a file and it still errors:
96
- - Read the error message carefully — it may be a different issue
97
- - Use `web_search` or `task(web-researcher)` to understand the correct API
98
- - Try a fundamentally different approach, not a variation of the same one
99
-
100
- ## Dev Server
101
-
102
- When starting a dev server:
103
- 1. Run `exec({ command: "npm install", cwd: "web-application" })` if `node_modules` is missing
104
- 2. Use `exec({ command: "npm run dev", cwd: "web-application", background: true })` to start in background
105
- 3. Use `getLogs({ sessionId, commandId })` to check output and wait for ready
106
- 4. Extract the actual port from logs (e.g., "localhost:5173", "127.0.0.1:3001")
107
- 5. Use that detected port in `showPreview({ port: DETECTED_PORT, title: "Dev Server" })`
108
- 6. Only if no port found in logs, fallback to `showPreview({ port: 3000, title: "Dev Server" })`
109
-
110
- ## Database — Neon PostgreSQL
111
-
112
- - **ALWAYS use `@neondatabase/serverless`** — it uses HTTP/WebSocket, compatible with Workers
113
- - API: `import { neon } from '@neondatabase/serverless'`
114
- - For simple queries: `const sql = neon(process.env.DATABASE_URL); const rows = await sql`SELECT * FROM users`;`
115
- - For ORM: use `drizzle-orm` + `drizzle-orm/neon-http`
116
-
117
- ### Database Provisioning
118
- 1. First check if `DATABASE_URL` already exists via `list_env_vars`
119
- 2. If not — use `create_database` tool to provision a Neon DB (it auto-sets `DATABASE_URL`)
120
- 3. **NEVER ask the user to provide DATABASE_URL** — the platform provisions databases automatically
121
- 4. Only use `requestEnvVar` for DATABASE_URL if the user explicitly wants their own external database
122
-
123
- ### Critical: Lazy Initialization
124
- `neon()` must **NEVER** be called at module top level. In Cloudflare Workers, `process.env` is only populated inside the `fetch()` handler. Module-level `neon(process.env.DATABASE_URL)` will crash with `undefined`. Always use a lazy singleton — see the `db()` pattern in `api-creation` and `authentication` skills.
125
-
126
- ## Packages Compatible with Workers
127
-
128
- | Package | Purpose |
129
- |---------|---------|
130
- | `@neondatabase/serverless` | PostgreSQL via HTTP (Neon) |
131
- | `drizzle-orm` + `drizzle-orm/neon-http` | ORM for Neon (~7kb) |
132
- | `kysely` | Lightweight query builder (pure TS) |
133
- | `@planetscale/database` | MySQL via HTTP |
134
- | `@upstash/redis` | Redis via HTTP |
135
- | `@libsql/client/web` | Turso/libSQL via HTTP |
136
- | `jose` | JWT/JWE/JWS (WebCrypto native) |
137
- | `bcryptjs` | Password hashing (pure JS) |
138
- | `zod` | Schema validation |
139
- | `fetch` | Built-in, no import needed |
140
-
141
- ## Background Commands
142
-
143
- Use `background: true` for long-running commands:
144
- - `npx -y shadcn@latest add ...` → wait 20-40 seconds
145
- - `npm install` with many deps → wait 20-30 seconds
146
- - `npm run build` → wait 15-45 seconds
147
- - `npm run dev` (server startup) → wait 5-10 seconds
148
-
149
- After starting in background, call `wait({ seconds: N })`, then `getLogs` to check. If still running, wait again (5-10s) and re-check. Do NOT call `getLogs` repeatedly without waiting.
1
+ ---
2
+ name: reference
3
+ description: Essential reference for stack versions, APIs, common errors, and patterns. Read this BEFORE writing any code in a TanStack Start project to avoid wrong imports, deprecated APIs, and build errors.
4
+ ---
5
+
6
+ # Reference — Stack Versions & Patterns
7
+
8
+ ## When to Read This Skill
9
+
10
+ - **ALWAYS** before writing code that uses TanStack Start, Tailwind CSS, or shadcn/ui
11
+ - Before debugging build or runtime errors
12
+ - Before setting up a dev server
13
+ - When unsure about correct import paths or API syntax
14
+
15
+ ## Stack Versions
16
+
17
+ | Package | Version | Key Changes |
18
+ |---------|---------|-------------|
19
+ | React | 19.x | `use()`, `useActionState()`, `useOptimistic()`, ref as prop (no forwardRef) |
20
+ | TanStack Start | 1.x | `createServerFn()` with fluent API, Nitro server, config in `vite.config.ts` |
21
+ | TanStack Router | 1.x | `createFileRoute()`, `Link`, `useNavigate()`, `useParams()`, `useSearch()` |
22
+ | Vite | 7.x | `@tailwindcss/vite` plugin, `@tanstack/react-start/plugin/vite` |
23
+ | Tailwind CSS | 4.x | CSS-based config via `@theme {}` — **NO `tailwind.config.js`** |
24
+ | shadcn/ui | latest | OKLCH colors, `tw-animate-css` (NOT `tailwindcss-animate`), `@custom-variant dark` |
25
+ | TypeScript | 5.7+ | strict mode |
26
+
27
+ ## Tailwind CSS 4 — Critical Differences from v3
28
+
29
+ - Config lives in `src/styles.css` using `@import "tailwindcss"` and `@theme {}` blocks
30
+ - **NO `tailwind.config.js`** — delete it if it exists
31
+ - Colors use OKLCH format, not HSL
32
+ - Custom properties: `--color-primary`, `--color-background`, etc. inside `@theme inline {}`
33
+ - Plugins loaded via CSS: `@plugin "..."` — NOT via JS config
34
+ - No `content` array needed — auto-detection
35
+ - Animation: use `tw-animate-css`, NOT `tailwindcss-animate`
36
+
37
+ ## TanStack Start API
38
+
39
+ ### Config
40
+ Config is in `vite.config.ts` with `tanstackStart()` plugin. **NOT** old `app.config.ts` with `defineConfig`.
41
+
42
+ ### Server Functions
43
+ ```typescript
44
+ import { createServerFn } from '@tanstack/react-start'
45
+ import { z } from 'zod'
46
+
47
+ const mySchema = z.object({ id: z.string() })
48
+
49
+ export const getData = createServerFn({ method: 'GET' })
50
+ .inputValidator((d: unknown) => mySchema.parse(d))
51
+ .handler(async ({ data }) => {
52
+ // data is typed as { id: string }
53
+ return { result: data.id }
54
+ })
55
+ ```
56
+
57
+ **IMPORTANT:** `.inputValidator()` takes a **FUNCTION**, not a schema directly. Always wrap zod: `.inputValidator((d: unknown) => mySchema.parse(d))`
58
+
59
+ ### File-Based Routing
60
+ - `$param` for dynamic segments
61
+ - `_layout` prefix for pathless layouts
62
+ - `__root.tsx` for root layout
63
+ - Loaders: defined on route via `loader` option in `createFileRoute()`
64
+
65
+ ## Common Errors & Recovery
66
+
67
+ ### Build / Compile Errors
68
+ | Error | Fix |
69
+ |-------|-----|
70
+ | `Cannot find module 'X'` | Run `npm install` first, then retry |
71
+ | `Type error: ...` | Read the file, fix the type, rebuild |
72
+ | `ENOENT: no such file or directory` | Check the path — likely wrong relative path |
73
+
74
+ ### Dev Server Errors
75
+ | Error | Fix |
76
+ |-------|-----|
77
+ | Port already in use | Kill the background process, restart on a different port |
78
+ | `MODULE_NOT_FOUND` after install | `rm -rf node_modules && npm install` |
79
+
80
+ ### Package Install Errors
81
+ | Error | Fix |
82
+ |-------|-----|
83
+ | `ERESOLVE: peer dependency conflict` | Use `npm install --legacy-peer-deps` |
84
+ | `ETARGET: no matching version` | Check the actual package name/version with `web_search` |
85
+
86
+ ### Recovery Pattern
87
+ 1. Read the **FULL** error message (don't guess from partial output)
88
+ 2. Check `getLogs` if it was a background command
89
+ 3. Fix the root cause (don't retry the same failing command)
90
+ 4. **NEVER repeat the same edit or command twice** — if your fix didn't work, try a DIFFERENT approach
91
+ 5. If stuck after 2 attempts, use `web_search` to find the solution
92
+ 6. If still stuck, use `askUser` to explain the problem and ask for guidance
93
+
94
+ ### Do NOT Loop
95
+ If you edited a file and it still errors:
96
+ - Read the error message carefully — it may be a different issue
97
+ - Use `web_search` or `task(web-researcher)` to understand the correct API
98
+ - Try a fundamentally different approach, not a variation of the same one
99
+
100
+ ## Dev Server
101
+
102
+ When starting a dev server:
103
+ 1. Run `exec({ command: "npm install", cwd: "web-application" })` if `node_modules` is missing
104
+ 2. Use `exec({ command: "npm run dev", cwd: "web-application", background: true })` to start in background
105
+ 3. Use `getLogs({ sessionId, commandId })` to check output and wait for ready
106
+ 4. Extract the actual port from logs (e.g., "localhost:5173", "127.0.0.1:3001")
107
+ 5. Use that detected port in `showPreview({ port: DETECTED_PORT, title: "Dev Server" })`
108
+ 6. Only if no port found in logs, fallback to `showPreview({ port: 3000, title: "Dev Server" })`
109
+
110
+ ## Database — Neon PostgreSQL
111
+
112
+ - **ALWAYS use `@neondatabase/serverless`** — it uses HTTP/WebSocket, compatible with Workers
113
+ - API: `import { neon } from '@neondatabase/serverless'`
114
+ - For simple queries: `const sql = neon(process.env.DATABASE_URL); const rows = await sql`SELECT * FROM users`;`
115
+ - For ORM: use `drizzle-orm` + `drizzle-orm/neon-http`
116
+
117
+ ### Database Provisioning
118
+ 1. First check if `DATABASE_URL` already exists via `list_env_vars`
119
+ 2. If not — use `create_database` tool to provision a Neon DB (it auto-sets `DATABASE_URL`)
120
+ 3. **NEVER ask the user to provide DATABASE_URL** — the platform provisions databases automatically
121
+ 4. Only use `requestEnvVar` for DATABASE_URL if the user explicitly wants their own external database
122
+
123
+ ### Critical: Lazy Initialization
124
+ `neon()` must **NEVER** be called at module top level. In Cloudflare Workers, `process.env` is only populated inside the `fetch()` handler. Module-level `neon(process.env.DATABASE_URL)` will crash with `undefined`. Always use a lazy singleton — see the `db()` pattern in `api-creation` and `authentication` skills.
125
+
126
+ ## Packages Compatible with Workers
127
+
128
+ | Package | Purpose |
129
+ |---------|---------|
130
+ | `@neondatabase/serverless` | PostgreSQL via HTTP (Neon) |
131
+ | `drizzle-orm` + `drizzle-orm/neon-http` | ORM for Neon (~7kb) |
132
+ | `kysely` | Lightweight query builder (pure TS) |
133
+ | `@planetscale/database` | MySQL via HTTP |
134
+ | `@upstash/redis` | Redis via HTTP |
135
+ | `@libsql/client/web` | Turso/libSQL via HTTP |
136
+ | `jose` | JWT/JWE/JWS (WebCrypto native) |
137
+ | `bcryptjs` | Password hashing (pure JS) |
138
+ | `zod` | Schema validation |
139
+ | `fetch` | Built-in, no import needed |
140
+
141
+ ## Background Commands
142
+
143
+ Use `background: true` for long-running commands:
144
+ - `npx -y shadcn@latest add ...` → wait 20-40 seconds
145
+ - `npm install` with many deps → wait 20-30 seconds
146
+ - `npm run build` → wait 15-45 seconds
147
+ - `npm run dev` (server startup) → wait 5-10 seconds
148
+
149
+ After starting in background, call `wait({ seconds: N })`, then `getLogs` to check. If still running, wait again (5-10s) and re-check. Do NOT call `getLogs` repeatedly without waiting.