diff --git a/AGENTS.md b/AGENTS.md index 28f9236..ba1c7e7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,6 +5,10 @@ the extension uses chrome.debugger to manage the user browser read ./README.md for an overview of how this extension and mcp work read playwriter/src/prompt.md to understand how the MCP works +## backward compatibility + +breaking changes to the WS protocol MUST never be made. publishing the extension code will never be instant, which means the extension must keep working with newer versions of the MCP and WS relay server. + ## architecture - user installs the extension in chrome. we assume there is only one chrome window for now, the first opened. @@ -18,10 +22,16 @@ read playwriter/src/prompt.md to understand how the MCP works - a few more events need custom handling - tabs are identified by sessionId or targetId (CDP concepts) or tabId (chrome debugger concept only) +mcp.ts MUST never use console.log. only console.error + +write code that will run on all platforms: mac, linux, windows. especially around paths handling and command execution + ## development extension/ contains the chrome extension code. you need to run `pnpm build` to make it ready to be loaded in chrome. the extension folder chrome will use is extension/dist +when I ask you to release extension run package.json release script + playwriter contains the ws server and MCP code. also the tests for the mcp are there. playwriter/src/prompt.md contains the docs for the MCP the agent will use. you should add there important sections that help the agent control the browser well with the MCP interface playwriter/src/resource.md is for more generic knowledge about playwright that the agent can use when necessary, for things like best practices for selecting locators on the page @@ -75,16 +85,17 @@ when summarizing changes at the end of the message, be super short, a few words please ask questions and confirm assumptions before generating complex architecture code. -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. +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. NEVER commit yourself unless asked to do so. I will commit the code myself. -NEVER add comments unless I tell you +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! ## files always use kebab case for new filenames. never use uppercase letters in filenames +never write temporary files to /tmp. instead write them to a local ./tmp folder instead. make sure it is in .gitignore too ## see files in the repo @@ -126,8 +137,6 @@ you can open files when i ask me "open in zed the line where ..." using the comm - 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 -- 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 - - 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: - 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. @@ -142,6 +151,7 @@ you can open files when i ask me "open in zed the line where ..." using the comm - 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. +- NEVER silently suppress errors in catch {} blocks if they contain more than one function call ```ts // BAD. DO NOT DO THIS let favicon: string | undefined; @@ -325,26 +335,30 @@ if after doing this we still have duplicate packages, you will have to ask the u # testing -do not write new test files unless asked. do not write tests if there is not already a test or describe block for that function or module. +.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 + +never use timeouts longer than 5 seconds for expects and other statements timeouts. increase timeouts for tests if required, up to 1 minute + +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. 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 tests should validate complex and non-obvious logic. if a test looks like a placeholder, do not add it. -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. +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. 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. > always call `pnpm vitest` or `pnpm test` with `--run` or they will hang forever waiting for changes! > ALWAYS read back the test if you use the `-u` option to make sure the inline snapshots are as you expect. -- NEVER writes the snapshots content yourself in `toMatchInlineSnapshot`. instead leave it empty and call `pnpm test -u` to fill in snapshots content. +- 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 - 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. - 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 -never test client react components. only server code that runs on the server. +never test client react components. only React and browser independent code. 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. @@ -366,6 +380,7 @@ changelogs.md when generating a .md or .mdx file to document things, always add a frontmatter with title and description. also add a prompt field with the exact prompt used to generate the doc. use @ to reference files and urls and provide any context necessary to be able to recreate this file from scratch using a model. if you used urls also reference them. reference all files you had to read to create the doc. use yaml | syntax to add this prompt and never go over the column width of 80 # github + 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. ## creating issues and pull requests @@ -400,10 +415,26 @@ Error: Request timeout at /api/auth/login ```bash gh run list # lists latest actions runs gh run watch --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 +gh pr checks --watch --fail-fast # watch for current branch pr ci checks to finish gh run view --log-failed | tail -n 300 # read the logs for failed steps in the actions run gh run view --log | tail -n 300 # read all logs for a github actions run ``` +## responding to PR reviews and comments (gh-pr-review extension) + +```bash +# view reviews and get thread IDs +gh pr-review review view 42 -R owner/repo --unresolved + +# reply to a review comment +gh pr-review comments reply 42 -R owner/repo \ + --thread-id PRRT_kwDOAAABbcdEFG12 \ + --body "Fixed in latest commit" + +# resolve a thread +gh pr-review threads resolve 42 -R owner/repo --thread-id PRRT_kwDOAAABbcdEFG12 +``` + ## listing, searching, reading github repos files with gitchamber 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