117 lines
3.4 KiB
Markdown
117 lines
3.4 KiB
Markdown
# WriteUserScript
|
|
|
|
Creates or overwrites a Playwright browser-macro in the caller's
|
|
`browser-macros/` folder.
|
|
|
|
> **Retired (2026-06):** plain-Node `scripts/` (the old `kind: 'script'`) and
|
|
> `templates/` were removed. Keep reusable procedures/boilerplate in **Skills**,
|
|
> and run ad-hoc code with the **Bash** tool. Passing `kind: 'script'` now
|
|
> returns an error pointing at those replacements.
|
|
|
|
| directory | runtime | signature |
|
|
|-----------|---------|-----------|
|
|
| `browser-macros/` | Playwright — Chromium | `main({ context, params })` |
|
|
|
|
## Input
|
|
|
|
```ts
|
|
{
|
|
name: string, // slug — '.js' appended if absent
|
|
content: string, // full file text (frontmatter + main())
|
|
overwrite?: boolean // default: false — error if file exists
|
|
}
|
|
```
|
|
|
|
## Required file structure
|
|
|
|
The content must define a `main` function. The following forms are all accepted:
|
|
|
|
```js
|
|
// ES function declaration
|
|
async function main({ context, params }) { … }
|
|
|
|
// Arrow / assigned function
|
|
const main = async ({ context, params }) => { … };
|
|
|
|
// CommonJS export
|
|
module.exports = async function main({ context, params }) { … };
|
|
exports.main = async function({ context, params }) { … };
|
|
```
|
|
|
|
If none of these patterns is found the tool returns `isError: true` with a
|
|
hint to add a `main` definition.
|
|
|
|
## YAML frontmatter (recommended)
|
|
|
|
```yaml
|
|
---
|
|
description: One-line human-readable description shown in ListUserAssets
|
|
params:
|
|
- name: url
|
|
type: string
|
|
- name: limit
|
|
type: number
|
|
default: 10
|
|
---
|
|
```
|
|
|
|
Frontmatter is parsed by `RunUserScript` for param validation. Macros without
|
|
frontmatter still run, but param validation is skipped.
|
|
|
|
Macros may additionally declare `session_profile_id: <N>` to auto-load
|
|
a saved login session (see `RunUserScript` docs).
|
|
|
|
## Size limit
|
|
|
|
256 KB (UTF-8 encoded). Exceeding the limit returns `isError: true`.
|
|
|
|
## Overwrite semantics
|
|
|
|
By default (`overwrite: false`) writing to an existing file is an error.
|
|
Pass `overwrite: true` to replace the existing file atomically.
|
|
|
|
## When to use
|
|
|
|
- You discovered a useful browser-automation pattern during a task — save it for next time.
|
|
- The user asks you to create or update a macro they can run later via `RunUserScript`.
|
|
- You want to prototype a browser automation without going through the UI.
|
|
|
|
## Example
|
|
|
|
```js
|
|
WriteUserScript({
|
|
name: "screenshot-dashboard",
|
|
content: `---
|
|
description: Take a screenshot of the dashboard
|
|
params:
|
|
- name: url
|
|
type: string
|
|
---
|
|
async function main({ context, params }) {
|
|
const page = await context.newPage();
|
|
await page.goto(params.url);
|
|
const buf = await page.screenshot({ fullPage: true });
|
|
return { screenshotBase64: buf.toString('base64') };
|
|
}
|
|
`
|
|
})
|
|
```
|
|
|
|
## Error cases
|
|
|
|
| Situation | `isError` | message contains |
|
|
|-----------|-----------|-----------------|
|
|
| No authenticated user | true | "authenticated" |
|
|
| Retired `kind: 'script'` passed | true | "retired" |
|
|
| `name` missing / empty | true | `"name"` |
|
|
| `name` contains `/`, space, etc. | true | "alphanumeric" |
|
|
| `content` missing `main` | true | "main" |
|
|
| Content exceeds 256 KB | true | "bytes" |
|
|
| File exists, `overwrite` not set | true | "overwrite" |
|
|
|
|
## Notes
|
|
|
|
- `WriteUserScript` is a META_TOOL — available in every movement without listing it in `allowed_tools`.
|
|
- After writing, use `RunUserScript` to immediately execute and verify the macro.
|
|
- Use `ListUserAssets` to see all macros currently in the folder.
|