chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:28:42 +08:00
commit e09edc5f16
78 changed files with 12250 additions and 0 deletions
+187
View File
@@ -0,0 +1,187 @@
# CLI Tool Mode
Default Webwright runs (`/webwright:run`, plain prompt) produce a one-shot
`final_script.py` that solves the task for the literal values the user
provided. **CLI tool mode** (`/webwright:craft`) instead produces a
**reusable, parameterized CLI tool**: the same script can be re-run later
with different argument values to perform the same kind of task.
This mode is adapted from `webwright/src/webwright/config/crafted_cli.yaml`'s
"Final-Script Shape (CLI Tool, MANDATORY)" contract. The OpenAI-backed
`self_reflection` gate is replaced by your own self-verification against
`plan.md`.
## When to use
Trigger CLI tool mode when:
- the user invokes `/webwright:craft …`, or
- the user says "make it reusable", "parameterize", "turn this into a CLI",
"I want to call this again with different X", or similar.
Otherwise, stay in default one-shot mode.
## `plan.md` — add a `# Parameters` section
Before writing the script, identify every requirement the user could
plausibly vary and list them in `plan.md` **in addition to** the usual
`# Critical Points` checklist:
```markdown
# Task
<verbatim task description>
# Parameters
| name | type | source phrase from task | default | allowed / format |
|---------|------|-------------------------|-------------|-------------------------|
| <arg_a> | str | "..." | "<value>" | <format / allowed set> |
| <arg_b> | int | "..." | <value> | <range or units> |
| <arg_c> | str | "..." | "<value>" | <format> |
# Critical Points
- [ ] CP1: ...
- [ ] CP2: ...
```
Rules:
- Every entry in `# Parameters` must (a) become a function argument and
(b) become an `argparse --flag` with the listed default.
- Items that are truly fixed for the site (start URL, site name, selector
strategy) are NOT parameters — keep them hard-coded.
- Defaults reproduce the original task exactly. Running
`python final_script.py` with no arguments must reproduce the task.
- Critical Points are still required; they are the verification contract.
## `final_script.py` — required shape
1. **One reusable function** named after the task domain. Examples:
- `def search_<domain>(arg_a, arg_b, ...): ...`
- `def lookup_<entity>(query, filters): ...`
2. **Google-style docstring** with summary, full `Args:` block, and
`Returns:`. Each `Args:` entry documents:
- the argument name and type,
- what it represents in the task domain,
- accepted format / units / allowed values,
- the default (mirroring the `# Parameters` table).
```python
def search_<domain>(arg_a: str, arg_b: int, arg_c: str) -> dict:
"""<One-line summary of what this tool does on the target site>.
Args:
arg_a: <what it represents>; <format / allowed values>.
Default: "<value>".
arg_b: <what it represents>; <range / units>.
Default: <value>.
arg_c: <what it represents>; <format>.
Default: "<value>".
Returns:
dict with keys ``<key1>`` (<type>), ``<key2>`` (<type>),
"""
```
3. **`argparse` CLI** under `if __name__ == "__main__":`. Every function
argument has a matching `--<arg>` flag with `type=`, `help=` (copied
from the docstring), and `default=` equal to the concrete task value:
```python
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description=search_<domain>.__doc__.splitlines()[0])
parser.add_argument("--arg-a", dest="arg_a", type=str,
default="<value>",
help="<copied from docstring>")
parser.add_argument("--arg-b", dest="arg_b", type=int,
default=<value>,
help="<copied from docstring>")
parser.add_argument("--arg-c", dest="arg_c", type=str,
default="<value>",
help="<copied from docstring>")
args = parser.parse_args()
result = asyncio.run(_run(**vars(args)))
print(result)
```
4. **Side-effect-free at import time.** No browser launch, no network
call, no file write at module top-level. The reusable function must be
importable from another Python process without triggering a run.
5. **Action-log parameter echo.** The first line written to
`final_script_log.txt` after reset MUST be a `step 0 params: ...`
line listing every resolved argument as `name=value` pairs, e.g.:
```
step 0 params: arg_a=<value> arg_b=<value> arg_c=<value>
```
so the resolved inputs are visible in any verification pass.
6. Same instrumentation as default mode: viewport 1280×1800, headless
local Firefox, no `full_page=True`, screenshots saved as
`final_runs/run_<id>/screenshots/final_execution_<step>_<action>.png`,
final datum appended to `final_script_log.txt`.
## Verification (replaces `self_reflection`)
In addition to the default self-verification (every CP in `plan.md`
ticked with cited screenshot/log evidence), CLI mode requires:
1. **Reproduce the task with no arguments.** Inside a fresh
`final_runs/run_<id>/`:
```bash
cd final_runs/run_<id> && python final_script.py
```
The run must succeed end-to-end and produce the expected screenshots
and `step 0 params: ...` log line.
2. **Import-safety smoke test.** From any other directory:
```bash
python -c "import importlib.util, pathlib; \
spec = importlib.util.spec_from_file_location('fs', 'final_runs/run_<id>/final_script.py'); \
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m); \
print([n for n in dir(m) if not n.startswith('_')])"
```
This must complete instantly with no browser launch and print the
reusable function's name.
3. **Optional second run with a different argument value.** Demonstrates
parameterization actually works. Run inside `final_runs/run_<id>_alt/`
(or just save its log/screenshot folder there). Skip only if the
alternate value would clearly fail (e.g. an unsupported value on the
target site).
4. **Print `--help`.** End by showing the user:
```bash
python final_runs/run_<id>/final_script.py --help
```
## Completion gate (CLI mode)
Set the task complete only when **all** are true:
1. `plan.md` contains both `# Parameters` (with name, type, source phrase,
default, allowed/format) and `# Critical Points` checklists.
2. `final_script.py` defines exactly one reusable function with a
Google-style `Args:` docstring covering every parameter.
3. Every `# Parameters` entry maps 1-to-1 to a function argument **and**
an argparse `--flag` whose default equals the concrete task value.
4. The script is import-safe (smoke test passes).
5. `python final_script.py` (no args) inside `final_runs/run_<id>/`
reproduced the task; all CPs verified against saved screenshots and
the action log.
6. `step 0 params: ...` line is present in `final_script_log.txt`.
7. The user has seen the final datum **and** the `--help` output so they
know how to call the tool again with different arguments.
If any of those is false, do not declare done — diagnose, fix the script
(preserving the CLI shape), re-run inside the next `run_<id+1>/`, and
re-verify.