agentsdotmd 1.1.3 → 1.1.4
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.
- package/README +9 -8
- package/{changelog.md → changelogs.md} +1 -14
- package/core.md +13 -2
- package/github.md +31 -4
- package/opentui.md +53 -0
- package/orb.md +64 -0
- package/package.json +1 -1
- package/react-router.md +0 -34
- package/react.md +13 -5
- package/threejs.md +9 -0
- package/tiktoken.md +7 -0
- package/tmux.md +62 -0
- package/typescript.md +1 -2
- package/vercel-sandbox.md +85 -0
- package/vercel.md +108 -0
- package/vitest.md +8 -4
package/README
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
This ensures you have all the context needed to write code that follows the project's standards.
|
|
1
|
+
this repo has many documents i use in all my projects so i can share them and keep them updated in a centralized place.
|
|
3
2
|
|
|
4
|
-
##
|
|
3
|
+
## installation
|
|
5
4
|
|
|
6
5
|
```bash
|
|
7
6
|
npm install -g agentsdotmd
|
|
8
7
|
```
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## usage
|
|
10
|
+
|
|
11
|
+
the agentsdotmd is just a clit to download files from github. it let you download some md files and merge them into an agents.md output
|
|
11
12
|
|
|
12
13
|
```bash
|
|
13
|
-
agentsdotmd core.md typescript.md pnpm.md react.md sentry.md vitest.md
|
|
14
|
+
agentsdotmd core.md typescript.md pnpm.md react.md tmux.md sentry.md vitest.md changelogs.md docs-writing.md doppler.md cac.md github.md prisma.md react-router.md shadcn.md tailwind.md lucide.md spiceflow.md vercel-ai-sdk.md playwright.md zod.md stripe.md gitchamber.md fly.md
|
|
14
15
|
```
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
this will generate an `agents.md` file with all the coding guidelines concatenated together.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
you can also use local files by prefixing them with `./`:
|
|
19
20
|
|
|
20
21
|
```bash
|
|
21
22
|
agentsdotmd core.md ./my-custom-rules.md typescript.md
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
or use a different repository (a fork of this repo for example):
|
|
25
26
|
|
|
26
27
|
```bash
|
|
27
28
|
agentsdotmd --repo yourname/yourrepo file1.md file2.md
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
## 1.1.3
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- vitest.md instructions update
|
|
8
|
-
|
|
9
|
-
## 1.1.2
|
|
10
|
-
|
|
11
|
-
### Patch Changes
|
|
12
|
-
|
|
13
|
-
- Header comment in generated AGENTS.md instructing not to edit directly
|
|
14
|
-
- Instructions to create ./MY_AGENTS.md for custom instructions
|
|
1
|
+
# writing changelogs
|
|
15
2
|
|
|
16
3
|
after you make a change that is noteworthy, add an entry in the CHANGELOG.md file in the root of the package. there are 2 kinds of packages, public and private packages. private packages have a private: true field in package.json, public packages do not and instead have a version field in package.json. public packages are the ones that are published to npm.
|
|
17
4
|
|
package/core.md
CHANGED
|
@@ -4,17 +4,28 @@ when summarizing changes at the end of the message, be super short, a few words
|
|
|
4
4
|
|
|
5
5
|
please ask questions and confirm assumptions before generating complex architecture code.
|
|
6
6
|
|
|
7
|
-
NEVER run commands with & at the end to run them in the background. this is leaky and harmful! instead ask me to run commands in the background if needed.
|
|
7
|
+
NEVER run commands with & at the end to run them in the background. this is leaky and harmful! instead ask me to run commands in the background using tmux if needed.
|
|
8
8
|
|
|
9
9
|
NEVER commit yourself unless asked to do so. I will commit the code myself.
|
|
10
10
|
|
|
11
|
-
NEVER
|
|
11
|
+
NEVER use git to revert files to previous state if you did not create those files yourself! there can be user changes in files you touched, if you revert those changes the user will be very upset!
|
|
12
12
|
|
|
13
13
|
## files
|
|
14
14
|
|
|
15
15
|
always use kebab case for new filenames. never use uppercase letters in filenames
|
|
16
16
|
|
|
17
|
+
never write temporary files to /tmp. instead write them to a local ./tmp folder instead. make sure it is in .gitignore too
|
|
17
18
|
|
|
18
19
|
## see files in the repo
|
|
19
20
|
|
|
20
21
|
use `git ls-files | tree --fromfile` to see files in the repo. this command will ignore files ignored by git
|
|
22
|
+
|
|
23
|
+
## handling unexpected file contents after a read or write
|
|
24
|
+
|
|
25
|
+
if you find code that was not there since the last time you read the file it means the user or another agent edited the file. do not revert the changes that were added. instead keep them and integrate them with your new changes
|
|
26
|
+
|
|
27
|
+
IMPORTANT: NEVER commit your changes unless clearly and specifically asked to!
|
|
28
|
+
|
|
29
|
+
## opening me files in zed to show me a specific portion of code
|
|
30
|
+
|
|
31
|
+
you can open files when i ask me "open in zed the line where ..." using the command `zed path/to/file:line`
|
package/github.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# github
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
you can use the `gh` cli to do operations on github for the current repository. For example: open issues, open PRs, check actions status, read workflow logs, etc.
|
|
4
5
|
|
|
5
6
|
## creating issues and pull requests
|
|
@@ -34,16 +35,42 @@ Error: Request timeout at /api/auth/login
|
|
|
34
35
|
```bash
|
|
35
36
|
gh run list # lists latest actions runs
|
|
36
37
|
gh run watch <id> --exit-status # if workflow is in progress, wait for the run to complete. the actions run is finished when this command exits. Set a tiemout of at least 10 minutes when running this command
|
|
38
|
+
gh pr checks --watch --fail-fast # watch for current branch pr ci checks to finish
|
|
37
39
|
gh run view <id> --log-failed | tail -n 300 # read the logs for failed steps in the actions run
|
|
38
40
|
gh run view <id> --log | tail -n 300 # read all logs for a github actions run
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
##
|
|
43
|
+
## responding to PR reviews and comments (gh-pr-review extension)
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# view reviews and get thread IDs
|
|
47
|
+
gh pr-review review view 42 -R owner/repo --unresolved
|
|
48
|
+
|
|
49
|
+
# reply to a review comment
|
|
50
|
+
gh pr-review comments reply 42 -R owner/repo \
|
|
51
|
+
--thread-id PRRT_kwDOAAABbcdEFG12 \
|
|
52
|
+
--body "Fixed in latest commit"
|
|
53
|
+
|
|
54
|
+
# resolve a thread
|
|
55
|
+
gh pr-review threads resolve 42 -R owner/repo --thread-id PRRT_kwDOAAABbcdEFG12
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## listing, searching, reading github repos files with gitchamber
|
|
42
59
|
|
|
43
|
-
you
|
|
60
|
+
you MUST use gitchamber.com to read repo files. first ALWAYS run `curl https://gitchamber.com` to read detailed usage docs. always use curl to fetch the responses of gitchamber.com
|
|
44
61
|
|
|
45
62
|
for example when working with the vercel ai sdk, you can fetch the latest docs using:
|
|
46
63
|
|
|
47
|
-
https://gitchamber.com/repos/
|
|
64
|
+
https://gitchamber.com/repos/facebook/react/main/files
|
|
65
|
+
|
|
66
|
+
https://gitchamber.com/repos/remorses/fumabase/main/files?glob=**/*.ts
|
|
67
|
+
|
|
68
|
+
https://gitchamber.com/repos/facebook/react/main/files/README.md?start=10&end=50
|
|
69
|
+
|
|
70
|
+
https://gitchamber.com/repos/facebook/react/main/search/useState
|
|
48
71
|
|
|
49
|
-
|
|
72
|
+
gitchamber allows you to list, search and read files in a repo. you MUST use it over alternatives likes raw.github.com, because
|
|
73
|
+
- it allows you to use context usage better via limit and offset pagination
|
|
74
|
+
- it can list files, even filtering by a specific glob (default is *.md and *.mdx)
|
|
75
|
+
- it can search a repo for a specific substring
|
|
76
|
+
- it can show the code with line numbers for each line, letting you find a specific line number
|
package/opentui.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
|
|
2
|
+
## opentui
|
|
3
|
+
|
|
4
|
+
opentui is the framework used to render the tui, using react.
|
|
5
|
+
|
|
6
|
+
IMPORTANT! before starting every task ALWAYS read opentui docs with `curl -s https://raw.githubusercontent.com/sst/opentui/refs/heads/main/packages/react/README.md`
|
|
7
|
+
|
|
8
|
+
do this every time you have to edit .tsx files in the project.
|
|
9
|
+
|
|
10
|
+
## React
|
|
11
|
+
|
|
12
|
+
NEVER NEVER use forwardRef. it is not needed. instead just use a ref prop like React 19 best practice
|
|
13
|
+
|
|
14
|
+
NEVER pass function or callbacks as dependencies of useEffect, this will very easily cause infinite loops if you forget to use useCallback
|
|
15
|
+
|
|
16
|
+
NEVER use useCallback other than for ref callbacks. it is useless if we never pass functions in useEffect dependencies
|
|
17
|
+
|
|
18
|
+
Try to never use useEffect if possible. usually you can move logic directly in event handlers instead
|
|
19
|
+
|
|
20
|
+
This is not a plain react project, instead it is a project using opentui renderer, which supports box, group, textarea, etc
|
|
21
|
+
|
|
22
|
+
Styles are implemented via Yoga. there is a style prop to pass an object or you can also pass styles using a prop for each style (which is preferred)
|
|
23
|
+
|
|
24
|
+
Not all CSS and react style props are implemented. Only flexbox one.
|
|
25
|
+
|
|
26
|
+
To understand how to use these components read other files in the project. try to use the theme.tsx file for colors.
|
|
27
|
+
|
|
28
|
+
## text wrapping
|
|
29
|
+
|
|
30
|
+
text elements wrap by default. to disable this pass wrapMode="none"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## researching opentui patterns
|
|
34
|
+
|
|
35
|
+
you can read more examples of opentui react code using gitchamber by listing and reading files from the correct endpoint: https://gitchamber.com/repos/sst/opentui/main/files?glob=packages/react/examples/**
|
|
36
|
+
|
|
37
|
+
or for example to see how to use the `<code>` opentui element: https://gitchamber.com/repos/sst/opentui/main/search/<code?glob=\*\*
|
|
38
|
+
|
|
39
|
+
do something like this for every new element you want to use and not know about, for exampel `<scrollbox>`, to see examples
|
|
40
|
+
|
|
41
|
+
## keys
|
|
42
|
+
|
|
43
|
+
cdm modifier (named hyper in opentui) cannot be intercepted in opentui. because parent terminal app will not forward it. instead use alt or ctrl
|
|
44
|
+
|
|
45
|
+
enter key is named return in opentui. alt is option.
|
|
46
|
+
|
|
47
|
+
## overlapping text in boxes
|
|
48
|
+
|
|
49
|
+
if you see text elements too close to each other the issues is probably that the content does not fit in the box row so elements shrink and gaps or paddings are no longer respected.
|
|
50
|
+
|
|
51
|
+
to fix this issue add flexShrink={0} to all elements inside the row
|
|
52
|
+
|
|
53
|
+
this common when using wrapMode none.
|
package/orb.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# OrbStack Linux VM
|
|
2
|
+
|
|
3
|
+
use `orb` to run commands in a persistent linux VM. useful for linux-only debugging or isolated experiments.
|
|
4
|
+
|
|
5
|
+
## running commands
|
|
6
|
+
|
|
7
|
+
orb automatically uses your current mac directory and can access mac files directly:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
orb uname -a # run command in default machine
|
|
11
|
+
orb ls # lists files in current mac directory
|
|
12
|
+
orb ./script.sh # run a script from current directory
|
|
13
|
+
orb # open interactive shell
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## installing packages
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
orb sudo apt-get update
|
|
20
|
+
orb sudo apt-get install -y nodejs npm
|
|
21
|
+
orb node --version
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## file paths
|
|
25
|
+
|
|
26
|
+
mac directories are a shared filesystem (not synced). this means:
|
|
27
|
+
|
|
28
|
+
- changes are instant in both directions, no delay
|
|
29
|
+
- files created in orb (in mac paths) appear immediately on mac
|
|
30
|
+
- files created on mac appear immediately in orb
|
|
31
|
+
- it's the same file, not a copy
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
orb touch foo.txt # appears immediately on mac
|
|
35
|
+
touch bar.txt # appears immediately in orb
|
|
36
|
+
orb cat bar.txt # can read mac-created file instantly
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
path mapping:
|
|
40
|
+
|
|
41
|
+
- mac paths like `/Users/...` work directly in orb commands (auto-translated)
|
|
42
|
+
- from inside linux shell, mac files are also accessible at `/mnt/mac/...`
|
|
43
|
+
- files in `/home/morse/` are accessible from mac at `~/OrbStack/<machine>/home/morse/...`
|
|
44
|
+
- `/tmp/` is a tmpfs (RAM) - isolated from mac, lost on reboot
|
|
45
|
+
|
|
46
|
+
## avoiding file pollution
|
|
47
|
+
|
|
48
|
+
NEVER run commands in orb that create files in the current mac directory. since the filesystem is shared, these files will pollute your mac project:
|
|
49
|
+
|
|
50
|
+
- node_modules (linux binaries)
|
|
51
|
+
- build outputs (dist/, .next/, etc)
|
|
52
|
+
- downloads
|
|
53
|
+
- caches
|
|
54
|
+
|
|
55
|
+
instead, copy the project to `/tmp` and work there:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
orb cp -r . /tmp/linux-vm-myproject
|
|
59
|
+
orb bash -c 'cd /tmp/linux-vm-myproject && npm install'
|
|
60
|
+
orb bash -c 'cd /tmp/linux-vm-myproject && npm run build'
|
|
61
|
+
orb bash -c 'cd /tmp/linux-vm-myproject && npm test'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`/tmp` is a tmpfs (RAM filesystem) - fully isolated from mac but files are lost on VM reboot.
|
package/package.json
CHANGED
package/react-router.md
CHANGED
|
@@ -201,40 +201,6 @@ so that internal navigation is done client side and is faster. notice that navig
|
|
|
201
201
|
|
|
202
202
|
ALWAYS use link components instead of the navigate function if possible. for example, in a dropdown component you should wrap the dropdown item in a link instead of adding an onClick handler.
|
|
203
203
|
|
|
204
|
-
# Creating New React Router Routes and Handling Types
|
|
205
|
-
|
|
206
|
-
When creating a new React Router route, follow these steps:
|
|
207
|
-
|
|
208
|
-
## 1. Create the route file
|
|
209
|
-
Create a file in `src/routes/` using flat routes naming convention (dots for separators, $ for params, kebab-case).
|
|
210
|
-
|
|
211
|
-
## 2. Generate types
|
|
212
|
-
**IMPORTANT**: Types are NOT automatically generated. After creating a route, run:
|
|
213
|
-
```bash
|
|
214
|
-
pnpm exec react-router typegen
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
## 3. Import Route types
|
|
218
|
-
```typescript
|
|
219
|
-
import type { Route } from './+types/your-route-name'
|
|
220
|
-
```
|
|
221
|
-
Note: The `+types` directory doesn't physically exist - it's virtual/generated.
|
|
222
|
-
|
|
223
|
-
## 4. Verify with typecheck
|
|
224
|
-
```bash
|
|
225
|
-
pnpm typecheck # This runs typegen first, then tsc
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
## Troubleshooting Missing Types
|
|
229
|
-
- Types missing? Run `pnpm exec react-router typegen`
|
|
230
|
-
- Import failing? Check filename matches import path exactly
|
|
231
|
-
- The `+types` directory is virtual - don't look for it in the filesystem
|
|
232
|
-
|
|
233
|
-
## Best Practices
|
|
234
|
-
- Always run `pnpm typecheck` after creating/modifying routes
|
|
235
|
-
- Export `Route` type from layout routes for child routes to import
|
|
236
|
-
- Use `href()` for all internal paths, even in redirects
|
|
237
|
-
|
|
238
204
|
## debugging build failures
|
|
239
205
|
|
|
240
206
|
when you build the website always pipe the output to a file so you can later grep inside it for errors. with `pnpm build 2>&1 | build.log`
|
package/react.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
- too many `useState` calls are bad. if some piece of state is dependent on other state just compute it as an expression in render. do not add new state unless strictly necessary. before adding a new useState to a component, use @think tool to think hard if you can instead: use expression with already existing local state, use expression with some global state, use expression with loader data, use expression with some other existing variable instead. for example if you need to show a popover when there is an error you should use the error as open state for the popover instead of adding new useState hook
|
|
14
14
|
|
|
15
|
-
- `useCallback` is bad. it should be always avoided.
|
|
15
|
+
- `useCallback` is bad. it should be always avoided unless for ref props. ref props ALWAYS need to be passed memoized functions or the component could remount on ever render!
|
|
16
16
|
|
|
17
17
|
- NEVER pass functions to useEffect or useMemo dependencies. when you start passing functions to hook dependencies you need to add useCallback everywhere in the code, useCallback is a virus that infects the codebase and should be ALWAYS avoided.
|
|
18
18
|
|
|
@@ -42,10 +42,18 @@
|
|
|
42
42
|
|
|
43
43
|
zustand is the preferred way to created global React state. put it in files like state.ts or x-state.ts where x is something that describe a portion of app state in case of multiple global states or multiple apps
|
|
44
44
|
|
|
45
|
-
- minimize number of props. do not use props if you can use zustand state instead. the app has global zustand state that lets you get a piece of state down from the component tree by using something like `useStore(x => x.something)` or `useLoaderData<typeof loader>()` or even useRouteLoaderData if you are deep in the react component tree
|
|
46
|
-
|
|
47
|
-
- do not consider local state truthful when interacting with server. when interacting with the server with rpc or api calls never use state from the render function as input for the api call. this state can easily become stale or not get updated in the closure context. instead prefer using zustand `useStore.getState().stateValue`. notice that useLoaderData or useParams should be fine in this case.
|
|
48
|
-
|
|
49
45
|
- NEVER add zustand state setter methods. instead use useStore.setState to set state. For example never add a method `setVariable` in the state type. Instead call `setState` directly
|
|
50
46
|
|
|
51
47
|
- zustand already merges new partial state with the previous state. NEVER DO `useStore.setState({ ...useStore.getInitialState(), ... })` unless for resetting state
|
|
48
|
+
|
|
49
|
+
## non controlled input components
|
|
50
|
+
|
|
51
|
+
some components do not have a value prop to set the value via React state. these are called uncontrolled components. Instead they usually let you get the current input value via ref. something like ref.current.value. They usually also have an onChange prop that let you know when the value changes
|
|
52
|
+
|
|
53
|
+
these usually have a initialValue or defaultValue to programmatically set the initial value of the input
|
|
54
|
+
|
|
55
|
+
when using these components you SHOULD not track their state via React: instead you should programmatically set their value and read their value via refs in event handlers
|
|
56
|
+
|
|
57
|
+
tracking uncontrolled inputs via React state means that you will need to add useEffect to programmatically change their value when our state changes. this is an anti pattern. instead you MUST keep in mind the uncontrolled input manages its own state and we interface with it via refs and initialValue prop.
|
|
58
|
+
|
|
59
|
+
using React state in these cases is only necessary if you have to show the input value during render. if that is not the case you can just use `inputRef.current.value` instead and set the value via `inputRef.current.value = something`
|
package/threejs.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# three.js
|
|
2
|
+
|
|
3
|
+
to read three.js manual you can see available pages with
|
|
4
|
+
|
|
5
|
+
`curl -Ls https://gitchamber.com/repos/mrdoob/three.js/dev/files?glob=manual/en/**/*.html`
|
|
6
|
+
|
|
7
|
+
reading about TLS, to create webgpu shaders
|
|
8
|
+
|
|
9
|
+
`curl -L https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language.md`
|
package/tiktoken.md
ADDED
package/tmux.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
|
|
2
|
+
Use tmux to run long-lived background commands as background “tasks” like vite dev servers, commands with watch mode.
|
|
3
|
+
Each task should be a tmux **session** that the agent can start, inspect, and stop via CLI.
|
|
4
|
+
|
|
5
|
+
ALWAYS give long and descriptive names for the sessions, so other agents know what they are for.
|
|
6
|
+
|
|
7
|
+
Run a background task (e.g. Vite dev server) without blocking:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
tmux new-session -d -s project-name-vite-dev-port-8034 'cd /path/to/project && npm run dev --port 8034'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Every time you are about to start a new session, first check if there is one already.
|
|
14
|
+
|
|
15
|
+
List all background tasks (sessions):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
tmux ls
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You can assume sessions that do not have names were not started by you or agents so you can ignore them
|
|
22
|
+
|
|
23
|
+
Kill a background task:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
tmux kill-session -t vite-dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Never attach to a session. You are inside a non TTY terminal, meaning you instead will have to read the latest n logs instead.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Fetch the last N log lines for a task without attaching (returns immediately):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
tmux capture-pane -t vite-dev:0 -S -100 -p
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Example pattern for a coding agent:
|
|
39
|
+
|
|
40
|
+
1. Start a task:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
tmux new-session -d -s build 'cd /repo && npm run build'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
2. Poll logs:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
tmux capture-pane -t build:0 -S -80 -p
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
3. List all running tasks:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
tmux ls
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
4. Stop a task when done:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
tmux kill-session -t build
|
|
62
|
+
```
|
package/typescript.md
CHANGED
|
@@ -24,8 +24,6 @@
|
|
|
24
24
|
|
|
25
25
|
- NEVER do `(x as any).field` or `'field' in x` before checking if the code compiles first without it. the code probably doesn't need any or the in check. even if it does not compile, use think tool first! before adding (x as any).something, ALWAYS read the .d.ts to understand the types
|
|
26
26
|
|
|
27
|
-
- after any change to typescript code ALWAYS run the `pnpm typecheck` script of that package, or if there is no typecheck script run `pnpm tsc` yourself
|
|
28
|
-
|
|
29
27
|
- do not declare uninitialized variables that are defined later in the flow. instead use an IIFE with returns. this way there is less state. also define the type of the variable before the iife. here is an example:
|
|
30
28
|
|
|
31
29
|
- use || over in: avoid 'x' in obj checks. prefer doing `obj?.x || ''` over doing `'x' in obj ? obj.x : ''`. only use the in operator if that field causes problems in typescript checks because typescript thinks the field is missing, as a last resort.
|
|
@@ -40,6 +38,7 @@
|
|
|
40
38
|
|
|
41
39
|
- if you encounter typescript lint errors for an npm package, read the node_modules/package/\*.d.ts files to understand the typescript types of the package. if you cannot understand them, ask me to help you with it.
|
|
42
40
|
|
|
41
|
+
- NEVER silently suppress errors in catch {} blocks if they contain more than one function call
|
|
43
42
|
```ts
|
|
44
43
|
// BAD. DO NOT DO THIS
|
|
45
44
|
let favicon: string | undefined;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Vercel Sandbox
|
|
2
|
+
|
|
3
|
+
use `sandbox` CLI to run commands in ephemeral remote Linux VMs. useful for isolated code execution, testing untrusted code, or running agent-generated scripts safely.
|
|
4
|
+
|
|
5
|
+
## running commands
|
|
6
|
+
|
|
7
|
+
sandbox runs commands non-interactively (no TTY needed):
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
sandbox run echo "hello world" # one-shot command
|
|
11
|
+
sandbox run node -e "console.log(2+2)" # run node code
|
|
12
|
+
sandbox run python -c "print('hello')" # run python (use --runtime python3.13)
|
|
13
|
+
sandbox run --rm ls -la # auto-cleanup after command
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
for multiple commands, manage sandbox lifecycle manually:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
ID=$(sandbox create -q) # create sandbox, get ID
|
|
20
|
+
sandbox exec $ID node -e "console.log('step 1')"
|
|
21
|
+
sandbox exec $ID node -e "console.log('step 2')"
|
|
22
|
+
sandbox stop $ID # cleanup
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## installing packages
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
sandbox run --sudo dnf install -y golang # system packages (Amazon Linux)
|
|
29
|
+
sandbox run npm install express # npm packages
|
|
30
|
+
sandbox run pip install requests # python packages (with --runtime python3.13)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
available runtimes: `node22` (default), `python3.13`
|
|
34
|
+
|
|
35
|
+
## file paths
|
|
36
|
+
|
|
37
|
+
sandbox has an isolated filesystem. the writable directory is `/vercel/sandbox`:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
sandbox exec $ID touch /vercel/sandbox/foo.txt # works
|
|
41
|
+
sandbox exec $ID touch /home/test.txt # permission denied
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## copying files
|
|
45
|
+
|
|
46
|
+
use `sandbox cp` to transfer files between local and remote:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# copy local file to sandbox
|
|
50
|
+
sandbox cp ./script.js $ID:/vercel/sandbox/
|
|
51
|
+
|
|
52
|
+
# copy from sandbox to local
|
|
53
|
+
sandbox cp $ID:/vercel/sandbox/output.txt ./
|
|
54
|
+
|
|
55
|
+
# copy directory
|
|
56
|
+
sandbox cp -r ./src $ID:/vercel/sandbox/
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## reading logs
|
|
60
|
+
|
|
61
|
+
command output is returned directly from `sandbox exec` and `sandbox run`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# stdout is printed directly
|
|
65
|
+
sandbox run node -e "console.log('hello')"
|
|
66
|
+
# Output: hello
|
|
67
|
+
|
|
68
|
+
# capture output in a variable
|
|
69
|
+
OUTPUT=$(sandbox exec $ID node -e "console.log(JSON.stringify({ok:true}))")
|
|
70
|
+
echo $OUTPUT
|
|
71
|
+
|
|
72
|
+
# stderr is also printed
|
|
73
|
+
sandbox run node -e "console.error('warning')"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
for long-running processes or debugging:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# write logs to file, then retrieve
|
|
80
|
+
sandbox exec $ID bash -c "node app.js > /vercel/sandbox/app.log 2>&1"
|
|
81
|
+
sandbox cp $ID:/vercel/sandbox/app.log ./
|
|
82
|
+
|
|
83
|
+
# or tail logs in real-time (requires -t for streaming)
|
|
84
|
+
sandbox exec -t $ID tail -f /vercel/sandbox/app.log
|
|
85
|
+
```
|
package/vercel.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel
|
|
3
|
+
description: List deployments, check build status, and stream runtime logs with Vercel CLI
|
|
4
|
+
tags: [vercel, deployment, logs, cli]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# vercel
|
|
8
|
+
|
|
9
|
+
use the vercel cli to list deployments, check build status, and read runtime logs.
|
|
10
|
+
|
|
11
|
+
## listing deployments
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
vercel list # list recent deployments
|
|
15
|
+
vercel list --prod # list only production deployments
|
|
16
|
+
vercel list --limit 5 # limit results
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## deployment status and build logs
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
vercel inspect <deployment-url-or-id> # get deployment info and status
|
|
23
|
+
vercel inspect <deployment-url-or-id> --logs # print build logs
|
|
24
|
+
vercel inspect <deployment-url-or-id> --logs --wait # wait for build to complete, stream logs
|
|
25
|
+
vercel inspect <deployment-url-or-id> --wait --timeout=5m # wait with timeout
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## reading runtime logs
|
|
29
|
+
|
|
30
|
+
runtime logs only stream new logs from when you start the command. there is no way to fetch historical logs via cli.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
vercel logs <deployment-url-or-id> # stream logs for 5 minutes
|
|
34
|
+
vercel logs <deployment-url-or-id> --json # output as json (useful for filtering)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> the `--since`, `--limit`, and `--follow` options are deprecated and ignored. use the vercel dashboard for historical logs.
|
|
38
|
+
|
|
39
|
+
## reading logs for latest deployment
|
|
40
|
+
|
|
41
|
+
get the latest production deployment url and stream its logs:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
DEPLOY_URL=$(vercel list --prod --limit 1 | tail -n 1 | awk '{print $1}')
|
|
45
|
+
vercel logs "$DEPLOY_URL"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
for preview deployments:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
DEPLOY_URL=$(vercel list --limit 1 | tail -n 1 | awk '{print $1}')
|
|
52
|
+
vercel logs "$DEPLOY_URL"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## background log streaming with tmux
|
|
56
|
+
|
|
57
|
+
since `vercel logs` streams indefinitely (up to 5 minutes), use tmux to run it in background while you trigger errors. see tmux.md for more details.
|
|
58
|
+
|
|
59
|
+
1. get latest deployment url:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
DEPLOY_URL=$(vercel list --prod --limit 1 | tail -n 1 | awk '{print $1}')
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
2. start log streaming in background:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
tmux new-session -d -s vercel-logs-prod "vercel logs $DEPLOY_URL --json"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. trigger an error (e.g. hit an endpoint that fails):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
curl -s "https://$DEPLOY_URL/api/some-endpoint" || true
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
4. read captured logs:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
tmux capture-pane -t vercel-logs-prod:0 -S -100 -p
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
5. filter for errors with jq:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
tmux capture-pane -t vercel-logs-prod:0 -S -200 -p | jq -s 'map(select(.level == "error"))'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
6. kill the session when done:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
tmux kill-session -t vercel-logs-prod
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## timeout wrapper
|
|
96
|
+
|
|
97
|
+
if you need logs for a fixed duration without tmux:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
timeout 30s vercel logs <deployment-url> --json > logs.json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## limitations
|
|
104
|
+
|
|
105
|
+
- runtime logs stream only, no historical fetch via cli
|
|
106
|
+
- logs retained 1 hour (cli) or 3 days (dashboard)
|
|
107
|
+
- build logs stored indefinitely (truncated at 4MB)
|
|
108
|
+
- for long-term storage use log drains (pro/enterprise)
|
package/vitest.md
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
# testing
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
.toMatchInlineSnapshot is the preferred way to write tests. leave them empty the first time, update them with -u. check git diff for the test file every time you update them with -u
|
|
4
|
+
|
|
5
|
+
never use timeouts longer than 5 seconds for expects and other statements timeouts. increase timeouts for tests if required, up to 1 minute
|
|
6
|
+
|
|
7
|
+
do not create dumb tests that test nothing. do not write tests if there is not already a test file or describe block for that function or module.
|
|
4
8
|
|
|
5
9
|
if the inputs for the tests is an array of repetitive fields and long content, generate this input data programmatically instead of hardcoding everything. only hardcode the important parts and generate other repetitive fields in a .map or .reduce
|
|
6
10
|
|
|
7
11
|
tests should validate complex and non-obvious logic. if a test looks like a placeholder, do not add it.
|
|
8
12
|
|
|
9
|
-
use vitest to run tests. tests should be run from the current package directory and not root. try using the test script instead of vitest directly. additional vitest flags can be added at the end, like --run to disable watch mode or -u to update snapshots.
|
|
13
|
+
use vitest or bun test to run tests. tests should be run from the current package directory and not root. try using the test script instead of vitest directly. additional vitest flags can be added at the end, like --run to disable watch mode or -u to update snapshots.
|
|
10
14
|
|
|
11
15
|
to understand how the code you are writing works, you should add inline snapshots in the test files with expect().toMatchInlineSnapshot(), then run the test with `pnpm test -u --run` or `pnpm vitest -u --run` to update the snapshot in the file, then read the file again to inspect the result. if the result is not expected, update the code and repeat until the snapshot matches your expectations. never write the inline snapshots in test files yourself. just leave them empty and run `pnpm test -u --run` to update them.
|
|
12
16
|
|
|
13
17
|
> always call `pnpm vitest` or `pnpm test` with `--run` or they will hang forever waiting for changes!
|
|
14
18
|
> ALWAYS read back the test if you use the `-u` option to make sure the inline snapshots are as you expect.
|
|
15
19
|
|
|
16
|
-
- NEVER
|
|
20
|
+
- NEVER write the snapshots content yourself in `toMatchInlineSnapshot`. instead leave it as is and call `pnpm test -u` to fill in snapshots content. the first time you call `toMatchInlineSnapshot()` you can leave it empty
|
|
17
21
|
|
|
18
22
|
- when updating implementation and `toMatchInlineSnapshot` should change, DO NOT remove the inline snapshots yourself, just run `pnpm test -u` instead! This will replace contents of the snapshots without wasting time doing it yourself.
|
|
19
23
|
|
|
20
24
|
- for very long snapshots you should use `toMatchFileSnapshot(filename)` instead of `toMatchInlineSnapshot()`. put the snapshot files in a snapshots/ directory and use the appropriate extension for the file based on the content
|
|
21
25
|
|
|
22
|
-
never test client react components. only
|
|
26
|
+
never test client react components. only React and browser independent code.
|
|
23
27
|
|
|
24
28
|
most tests should be simple calls to functions with some expect calls, no mocks. test files should be called the same as the file where the tested function is being exported from.
|
|
25
29
|
|