From a63aa06dddb539e24edfd7cc0b615cf0a4cd0bea Mon Sep 17 00:00:00 2001 From: dprevost-perso Date: Mon, 21 Sep 2026 06:11:31 -0400 Subject: [PATCH 1/2] chore: add committed commit-message skill under .agents/skills Mirrors webdriverio's .agents/ convention so the playbook is shared with the team instead of living in a personal, gitignored location. Co-Authored-By: Claude Sonnet 5 --- .agents/README.md | 4 +++ .agents/skills/commit/SKILL.md | 52 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 .agents/README.md create mode 100644 .agents/skills/commit/SKILL.md diff --git a/.agents/README.md b/.agents/README.md new file mode 100644 index 0000000..935673c --- /dev/null +++ b/.agents/README.md @@ -0,0 +1,4 @@ +# Agent toolchain + +- [`skills/`](skills) — playbooks for coding agents. Read a skill's + `SKILL.md` only when its description matches the task at hand. diff --git a/.agents/skills/commit/SKILL.md b/.agents/skills/commit/SKILL.md new file mode 100644 index 0000000..417777b --- /dev/null +++ b/.agents/skills/commit/SKILL.md @@ -0,0 +1,52 @@ +--- +name: commit +description: Create a git commit in this repo with a clear, terse, Conventional-Commits-style message. Use whenever the user asks to commit, save, or check in their changes, or types /commit — even if they just say "commit this" or "commit that" with no other detail. +--- + +Commit the current changes with a message that matches this repo's existing style: short, imperative, prefixed with a Conventional Commits type, and focused on *why* the change was made rather than restating the diff. + +## 1. Gather context + +Run these together, not sequentially, since none depends on the others: +- `git status` — see what's changed and what's untracked +- `git diff` (unstaged) and `git diff --staged` (already staged) — see the actual content +- `git log --oneline -15` — refresh on this repo's message style before writing one + +This repo's history is consistently `type: terse imperative summary`, e.g.: +``` +fix: serialize per-package releases in release.yml +fix: correct .npmignore packaging rules across all 3 driver packages +test: split edgedriver's unit.test.ts by source module +fix: harden edgedriver install.ts against Windows and Zip Slip bugs +``` +No bullet-point bodies, no restating every changed file — one line that says what changed and, where it's not obvious from the summary alone, why. Match that: `feat`, `fix`, `test`, `chore`, `docs`, `ci`, `refactor` are the types actually in use here. + +## 2. Stage deliberately + +Stage specific files by name (`git add path/to/file`), never a blanket `git add -A` or `git add .` — this repo's workflows and driver packages touch config, secrets-adjacent files (`.npmrc`, `.env*`, credentials), and generated output, and a blind add risks scooping up something that doesn't belong in the commit or the user didn't mean to include. + +Before staging, check `git status` for anything unexpected: files you didn't touch this session, or filenames that look like they could hold secrets even if the diff looks innocuous (`.env`, `credentials.json`, `*.pem`, `*token*`). If something looks off, flag it to the user instead of silently staging it. + +## 3. Write the message + +- One line, imperative mood, `type: summary` — no period at the end, matching the log above. +- Lead with *why*, not a mechanical restatement of the diff (bad: "update release.yml"; good: "detect which driver package changed before releasing 'all'"). +- Only add a body (blank line + short paragraph or bullets) if the one-liner genuinely can't carry the reasoning — this repo's history shows that's rare. Default to skipping it. +- Pick the type by what actually changed: `fix` for bug fixes, `feat` for new capability, `test` for test-only changes, `ci` for workflow/pipeline changes, `chore` for tooling/deps, `docs` for documentation only, `refactor` for no-behavior-change restructuring. + +## 4. Commit + +Pass the message via a heredoc so formatting survives: +```bash +git commit -m "$(cat <<'EOF' +type: terse summary here +EOF +)" +``` +Append whatever attribution footer this session's own instructions specify (check for a system reminder about commit attribution) — don't hardcode one here, since it can change independently of this skill. + +Never amend an existing commit unless the user explicitly asks for it — a fresh commit is the default even if a previous one was just made. Never pass `--no-verify` or otherwise skip hooks unless the user explicitly says to; if a pre-commit hook fails, fix the underlying issue and commit again rather than bypassing it. + +## 5. Confirm + +Run `git status` after the commit to confirm it landed cleanly, and report back in one line what was committed — don't dump the full diff back at the user, they already know what they changed. From 274c0496ba589820f5702afb0394e1b2576c774f Mon Sep 17 00:00:00 2001 From: dprevost-perso Date: Mon, 21 Sep 2026 06:48:57 -0400 Subject: [PATCH 2/2] More AI stuff --- .agents/README.md | 3 ++ .agents/skills/commit/SKILL.md | 52 ------------------ .agents/skills/concise-writing/SKILL.md | 56 ++++++++++++++++++++ .gitignore | 1 + AGENTS.md | 70 +++++++++++++++++++++++++ CLAUDE.md | 4 ++ 6 files changed, 134 insertions(+), 52 deletions(-) delete mode 100644 .agents/skills/commit/SKILL.md create mode 100644 .agents/skills/concise-writing/SKILL.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.agents/README.md b/.agents/README.md index 935673c..67707c0 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -1,4 +1,7 @@ # Agent toolchain +Canonical policy lives in [`/AGENTS.md`](../AGENTS.md). This directory only +holds: + - [`skills/`](skills) — playbooks for coding agents. Read a skill's `SKILL.md` only when its description matches the task at hand. diff --git a/.agents/skills/commit/SKILL.md b/.agents/skills/commit/SKILL.md deleted file mode 100644 index 417777b..0000000 --- a/.agents/skills/commit/SKILL.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -name: commit -description: Create a git commit in this repo with a clear, terse, Conventional-Commits-style message. Use whenever the user asks to commit, save, or check in their changes, or types /commit — even if they just say "commit this" or "commit that" with no other detail. ---- - -Commit the current changes with a message that matches this repo's existing style: short, imperative, prefixed with a Conventional Commits type, and focused on *why* the change was made rather than restating the diff. - -## 1. Gather context - -Run these together, not sequentially, since none depends on the others: -- `git status` — see what's changed and what's untracked -- `git diff` (unstaged) and `git diff --staged` (already staged) — see the actual content -- `git log --oneline -15` — refresh on this repo's message style before writing one - -This repo's history is consistently `type: terse imperative summary`, e.g.: -``` -fix: serialize per-package releases in release.yml -fix: correct .npmignore packaging rules across all 3 driver packages -test: split edgedriver's unit.test.ts by source module -fix: harden edgedriver install.ts against Windows and Zip Slip bugs -``` -No bullet-point bodies, no restating every changed file — one line that says what changed and, where it's not obvious from the summary alone, why. Match that: `feat`, `fix`, `test`, `chore`, `docs`, `ci`, `refactor` are the types actually in use here. - -## 2. Stage deliberately - -Stage specific files by name (`git add path/to/file`), never a blanket `git add -A` or `git add .` — this repo's workflows and driver packages touch config, secrets-adjacent files (`.npmrc`, `.env*`, credentials), and generated output, and a blind add risks scooping up something that doesn't belong in the commit or the user didn't mean to include. - -Before staging, check `git status` for anything unexpected: files you didn't touch this session, or filenames that look like they could hold secrets even if the diff looks innocuous (`.env`, `credentials.json`, `*.pem`, `*token*`). If something looks off, flag it to the user instead of silently staging it. - -## 3. Write the message - -- One line, imperative mood, `type: summary` — no period at the end, matching the log above. -- Lead with *why*, not a mechanical restatement of the diff (bad: "update release.yml"; good: "detect which driver package changed before releasing 'all'"). -- Only add a body (blank line + short paragraph or bullets) if the one-liner genuinely can't carry the reasoning — this repo's history shows that's rare. Default to skipping it. -- Pick the type by what actually changed: `fix` for bug fixes, `feat` for new capability, `test` for test-only changes, `ci` for workflow/pipeline changes, `chore` for tooling/deps, `docs` for documentation only, `refactor` for no-behavior-change restructuring. - -## 4. Commit - -Pass the message via a heredoc so formatting survives: -```bash -git commit -m "$(cat <<'EOF' -type: terse summary here -EOF -)" -``` -Append whatever attribution footer this session's own instructions specify (check for a system reminder about commit attribution) — don't hardcode one here, since it can change independently of this skill. - -Never amend an existing commit unless the user explicitly asks for it — a fresh commit is the default even if a previous one was just made. Never pass `--no-verify` or otherwise skip hooks unless the user explicitly says to; if a pre-commit hook fails, fix the underlying issue and commit again rather than bypassing it. - -## 5. Confirm - -Run `git status` after the commit to confirm it landed cleanly, and report back in one line what was committed — don't dump the full diff back at the user, they already know what they changed. diff --git a/.agents/skills/concise-writing/SKILL.md b/.agents/skills/concise-writing/SKILL.md new file mode 100644 index 0000000..22b49f5 --- /dev/null +++ b/.agents/skills/concise-writing/SKILL.md @@ -0,0 +1,56 @@ +--- +name: concise-writing +description: Keep everything written in this repo — commit messages, PR titles/descriptions, and code comments — clear and terse. Use whenever creating a git commit, opening or updating a pull request, or writing/reviewing a code comment; also covers /commit and requests like "commit this", "open a PR", or "write a comment explaining this". +--- + +Everything written *about* the code in this repo — commit messages, PR descriptions, code comments — should say the minimum needed to be understood, and no more. The reader (a maintainer, a reviewer, a future agent) can already read the diff; don't narrate it back to them. Say what isn't obvious from the code itself: the *why*, not the *what*. + +This applies across three surfaces. Jump to the one you need: + +## Commit messages + +Gather context first — run together, since none depends on the others: +- `git status` — what's changed and what's untracked +- `git diff` (unstaged) and `git diff --staged` — the actual content +- `git log --oneline -15` — refresh on this repo's message style + +This repo's history is consistently `type: terse imperative summary`, e.g.: +``` +fix: serialize per-package releases in release.yml +fix: correct .npmignore packaging rules across all 3 driver packages +test: split edgedriver's unit.test.ts by source module +fix: harden edgedriver install.ts against Windows and Zip Slip bugs +``` +- One line, imperative mood, `type: summary`, no trailing period. +- Lead with *why*, not a mechanical restatement of the diff (bad: "update release.yml"; good: "detect which driver package changed before releasing 'all'"). +- Only add a body if the one-liner genuinely can't carry the reasoning — rare in this repo's history. Default to skipping it. +- Pick the type by what changed: `fix`, `feat`, `test`, `ci`, `chore`, `docs`, `refactor`. + +**Staging**: stage specific files by name (`git add path/to/file`), never a blanket `git add -A` or `git add .` — this repo's workflows and driver packages touch config and secrets-adjacent files, and a blind add risks scooping up something that doesn't belong. Check `git status` first for anything unexpected or secret-looking (`.env`, `credentials.json`, `*.pem`, `*token*`) and flag it instead of silently staging it. + +**Committing**: pass the message via a heredoc so formatting survives: +```bash +git commit -m "$(cat <<'EOF' +type: terse summary here +EOF +)" +``` +Append whatever attribution footer this session's own instructions specify — don't hardcode one here, since it can change independently of this skill. + +Never amend an existing commit unless explicitly asked — a fresh commit is the default. Never pass `--no-verify` or otherwise skip hooks unless explicitly told to; if a pre-commit hook fails, fix the underlying issue and commit again. After committing, run `git status` to confirm it landed, and report back in one line what was committed — don't dump the full diff back at the user. + +## PR titles and descriptions + +- Title under ~70 characters, same "why, not what" rule as commit summaries. +- Body: a short `## Summary` (1-3 bullets, what changed and why it was needed — not a file-by-file listing the diff already shows) plus a `## Test plan` checklist of what was actually run. Skip sections that would just restate the diff. +- Don't repeat the same information across every commit in the PR *and* the PR description *and* a summary comment — pick the level (usually the PR description) and let the rest stay terse. +- When reviewing someone else's PR description for terseness, flag sentences that only restate a line from the diff without adding reasoning, and padding like "This PR also includes minor cleanup" with nothing concrete after it. + +## Code comments + +Default to no comment. Well-named functions and variables already say *what* the code does. Only add a comment when it carries information the code can't: +- a non-obvious constraint or invariant +- the reason for a workaround (link the issue/bug if there is one) +- behavior that would genuinely surprise a reader + +One line is almost always enough. This repo's existing multi-line comments are the exception that proves the rule — e.g. `packages/node-edgedriver/src/finder.ts` explains a 3-step platform-detection fallback that genuinely isn't obvious from the code alone — not a narration of what each line does. If removing a comment wouldn't leave a future reader confused, remove it. diff --git a/.gitignore b/.gitignore index da6894f..d3054dc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ coverage *.tgz *.tsbuildinfo .DS_Store +.claude/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..607e30e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,70 @@ +# AGENTS.md + +Entry point for coding agents in this repo. See [.agents/README.md](.agents/README.md) +for available skills — read a skill's `SKILL.md` when its description matches +the task, don't duplicate its rules here. + +No tool-specific agent config is committed beside `.agents/` — permissions, +hooks, and other per-tool settings (e.g. `.claude/`) stay personal and local, +never added to this repo. A thin adapter file like `CLAUDE.md` is the one +exception: it only points here, it doesn't hold its own copy of these rules. + +## Repo map + +pnpm workspace, no lerna/nx. The three driver packages are independent — +no shared dependencies between them, no monorepo-wide version to keep in sync: + +``` +packages/node-edgedriver Edge driver binary manager → npm: edgedriver +packages/node-geckodriver Firefox driver binary manager → npm: geckodriver +packages/node-safaridriver Safari driver manager → npm: safaridriver +packages/e2e real-browser e2e tests for all three +scripts/ shared build helpers (e.g. copy-cjs-pkg.mjs) +``` + +Each driver package has its own `.release-it.json`, `package.json` version, +and `.npmignore`. + +## Setup + +Node from [`.nvmrc`](.nvmrc) (24), pnpm pinned in `package.json#packageManager`. + +```sh +pnpm install +pnpm run build # tsc -b per package + CJS shim (scripts/copy-cjs-pkg.mjs) +``` + +`src/` edits aren't visible to tests or `postinstall` until rebuilt — use +`pnpm run watch` (all packages) or `pnpm --filter run watch` (one). + +## Test selection + +Don't default to `pnpm run checks:all` — it's lint + unit + e2e for every +package. Prefer the smallest proof: + +| Change | Run | +|---|---| +| One driver package | `pnpm --filter test` (that package's lint + unit) — `` is the npm name (`edgedriver`, `geckodriver`, `safaridriver`, `e2e`), not the `packages/node-*` directory name | +| Root config, `scripts/`, or more than one package | `pnpm run test:lint`, then `pnpm test` | +| Driver launch / real browser behavior | `pnpm run test:e2e` — needs real Edge/Firefox/Safari installed; CI runs it under xvfb on macOS/Linux/Windows, skip locally if you don't have the browsers | + +Lint is oxlint ([`.oxlintrc.json`](.oxlintrc.json)), not eslint — +`@stylistic/eslint-plugin` is only pulled in as an oxlint plugin. Husky runs +`test:lint` pre-commit and `pnpm test` pre-push; don't bypass either with +`--no-verify`. + +## Releases + +Manual, via the "Manual NPM Publish" GitHub Action +([.github/workflows/release.yml](.github/workflows/release.yml)) — never +automatic on merge. It runs `release-it` per package, tags as +`@`, and auto-skips packages with no changes since their +last tag when `driver: all` is selected (picking one driver explicitly always +releases it). Use `dryRun: yes` to exercise the whole flow without publishing +or tagging anything for real. + +## Working agreement + +Commit messages, PR descriptions, code comments, and how to stage changes: +see the [concise-writing](.agents/skills/concise-writing/SKILL.md) skill — +same "why, not what" rule across all of it. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2638049 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,4 @@ +# Claude Code + +Follow [AGENTS.md](./AGENTS.md). It is the canonical agent guide for this +repository. Do not add a second copy of those rules here.