Package audit scripts and update prompts for consumer repos

- Add `scripts/check-file-size.mjs` and `scripts/check-innerhtml.mjs` to `package.json` files list.
- Update `src/ops.mjs` to copy these scripts to `torch/scripts/` during `init` and `update` commands.
- Update all agent prompts in `src/prompts/` to reference `torch/scripts/` instead of `scripts/`.
- Ensure `torch/scripts/agent/` directory is created.
- Scripts are treated as "evolving" files (preserved on update unless forced).

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-14 18:04:15 +00:00
1 parent f10a3f9f9d
commit eb7ce149c7
11 files changed
+89 -50

No files matched your search

+2
View File
@@ -18,6 +18,8 @@
"src/torch-config.mjs",
"src/prompts/",
"src/docs/",
"scripts/check-file-size.mjs",
"scripts/check-innerhtml.mjs",
"skills/",
"dashboard/",
"assets/",
+39 -2
View File
@@ -6,6 +6,7 @@ const PKG_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'
// Source paths (in the package)
const SRC_PROMPTS_DIR = path.join(PKG_ROOT, 'src', 'prompts');
const SRC_SCRIPTS_DIR = path.join(PKG_ROOT, 'scripts');
// Files to treat as "Static" (always overwrite on update, with transformations)
const STATIC_FILES = [
@@ -17,6 +18,7 @@ const STATIC_FILES = [
// Directories containing "Evolving" files (copy if missing, preserve if present)
const EVOLVING_DIRS = ['daily', 'weekly'];
const EVOLVING_SCRIPTS = ['check-file-size.mjs', 'check-innerhtml.mjs'];
function getPaths(userRoot) {
const torchDir = path.join(userRoot, 'torch');
@@ -24,6 +26,7 @@ function getPaths(userRoot) {
root: userRoot,
torchDir,
promptsDir: path.join(torchDir, 'prompts'),
scriptsDir: path.join(torchDir, 'scripts'),
roster: path.join(torchDir, 'roster.json'),
};
}
@@ -62,6 +65,8 @@ export function cmdInit(force = false, cwd = process.cwd()) {
ensureDir(paths.torchDir);
ensureDir(paths.promptsDir);
ensureDir(paths.scriptsDir);
ensureDir(path.join(paths.scriptsDir, 'agent'));
// 1. Copy Roster (Evolving, but initially copied)
const srcRoster = path.join(SRC_PROMPTS_DIR, 'roster.json');
@@ -80,7 +85,17 @@ export function cmdInit(force = false, cwd = process.cwd()) {
}
}
// 3. Copy Prompts (Evolving)
// 3. Copy Scripts (Evolving)
for (const file of EVOLVING_SCRIPTS) {
const src = path.join(SRC_SCRIPTS_DIR, file);
const dest = path.join(paths.scriptsDir, file);
if (fs.existsSync(src)) {
copyFile(src, dest, false, true);
console.log(`Created ${path.relative(paths.root, dest)}`);
}
}
// 4. Copy Prompts (Evolving)
for (const dir of EVOLVING_DIRS) {
const srcDir = path.join(SRC_PROMPTS_DIR, dir);
const destDir = path.join(paths.promptsDir, dir);
@@ -149,7 +164,29 @@ export function cmdUpdate(force = false, cwd = process.cwd()) {
}
}
// 4. Update Prompts (Copy missing, preserve existing unless force)
// 4. Update Scripts (Copy missing, preserve existing unless force)
console.log('Updating scripts...');
ensureDir(paths.scriptsDir);
for (const file of EVOLVING_SCRIPTS) {
const src = path.join(SRC_SCRIPTS_DIR, file);
const dest = path.join(paths.scriptsDir, file);
if (fs.existsSync(src)) {
if (force) {
copyFile(src, dest, false, true);
console.log(` Updated ${file} (forced)`);
} else {
if (!fs.existsSync(dest)) {
copyFile(src, dest, false, true);
console.log(` Added ${file}`);
} else {
console.log(` Skipped ${file} (preserved)`);
}
}
}
}
// 5. Update Prompts (Copy missing, preserve existing unless force)
console.log('Updating prompts...');
for (const dir of EVOLVING_DIRS) {
const srcDir = path.join(SRC_PROMPTS_DIR, dir);
+6 -6
View File
@@ -40,8 +40,8 @@ PRIMARY WORKFLOW (end-to-end)
2. **Run audit scripts (report mode)**
- Run the three audit commands as stated:
- `node scripts/check-file-size.mjs --report 2>&1 | tee artifacts/audit/$(date +%F)/raw-check-file-size.log`
- `node scripts/check-innerhtml.mjs --report 2>&1 | tee artifacts/audit/$(date +%F)/raw-check-innerhtml.log`
- `node torch/scripts/check-file-size.mjs --report 2>&1 | tee artifacts/audit/$(date +%F)/raw-check-file-size.log`
- `node torch/scripts/check-innerhtml.mjs --report 2>&1 | tee artifacts/audit/$(date +%F)/raw-check-innerhtml.log`
- `npm run lint 2>&1 | tee artifacts/audit/$(date +%F)/raw-lint.log`
- If the repository uses `pnpm`/`yarn`, run lint with the repo’s recommended command from `package.json`.
- Save raw outputs in `artifacts/audit/YYYY-MM-DD/`.
@@ -124,9 +124,9 @@ ADDITIONAL GUIDANCE & BEST PRACTICES
===============================================================================
SEARCH / PARSING HELPER SCRIPTS (examples)
- Parse file-size raw log into JSON:
- `node scripts/parse-file-size-report.js artifacts/audit/YYYY-MM-DD/raw-check-file-size.log > artifacts/audit/YYYY-MM-DD/file-size-report.json`
- `node torch/scripts/parse-file-size-report.js artifacts/audit/YYYY-MM-DD/raw-check-file-size.log > artifacts/audit/YYYY-MM-DD/file-size-report.json`
- Parse innerHTML log similarly:
- `node scripts/parse-innerhtml-report.js ...`
- `node torch/scripts/parse-innerhtml-report.js ...`
- If the repo’s scripts support `--json` or `--output`, prefer those flags.
If such parsers do not exist, implement tiny Node scripts that reliably parse the scripts’ expected output.
@@ -212,8 +212,8 @@ FIRST-RUN CHECKLIST (do this now)
2. Create artifacts directory:
- `mkdir -p artifacts/audit/$(date +%F)`
3. Run the 3 audit scripts in report mode:
- `node scripts/check-file-size.mjs --report`
- `node scripts/check-innerhtml.mjs --report`
- `node torch/scripts/check-file-size.mjs --report`
- `node torch/scripts/check-innerhtml.mjs --report`
- `npm run lint`
- Save raw outputs to `artifacts/audit/$(date +%F)/`
- Record commands & outputs in `test_logs/TEST_LOG_<timestamp>.md`
+4 -4
View File
@@ -61,10 +61,10 @@ DETAILED WORKFLOW (step-by-step)
```
- (Adjust regex to include more candidates you want.)
- For a more robust approach, run an AST scan (Node/ES module) to find numeric literals:
- If comfortable, use `node` + `acorn` or `@babel/parser` to create a script (e.g., `scripts/find-numeric-literals.js`) that produces JSON output of numeric literals with file, line, column, and nearby AST context (identifier or property name).
- If comfortable, use `node` + `acorn` or `@babel/parser` to create a script (e.g., `torch/scripts/find-numeric-literals.js`) that produces JSON output of numeric literals with file, line, column, and nearby AST context (identifier or property name).
- Example (conceptual — script must be created first):
```
node scripts/find-numeric-literals.js js > perf/constants-refactor/numeric-literals.json
node torch/scripts/find-numeric-literals.js js > perf/constants-refactor/numeric-literals.json
```
- From results, group occurrences by numeric value and inspect contexts to find semantic similarity (timeouts, retries, TTLs).
@@ -188,8 +188,8 @@ rg --hidden --no-ignore -n --glob 'js/**/*.js' '\b(5000|10000|30000|60000|15000|
````
- AST-based approach (recommended for accuracy):
- Use `@babel/parser` to parse, walk nodes, and collect numeric literals with context (parent identifiers or property names). Example script:
- `scripts/find-numeric-literals.js` (create if needed)
- Run: `node scripts/find-numeric-literals.js js > perf/constants-refactor/numeric-literals.json`
- `torch/scripts/find-numeric-literals.js` (create if needed)
- Run: `node torch/scripts/find-numeric-literals.js js > perf/constants-refactor/numeric-literals.json`
- For replacements, prefer editor/IDE or `jscodeshift` transforms to keep edits safe and consistent:
- Example: create a `jscodeshift` codemod that replaces numeric literal with identifier and adds import.
- If using manual edits, ensure ESLint passes and imports are correct.
+11 -11
View File
@@ -2,13 +2,13 @@ You are: **decompose-agent**, a senior software engineer AI agent working inside
Your mission: **safely decompose a single large grandfathered file** (the largest one not decomposed recently) by extracting 2–3 cohesive blocks of logic into new modules. Keep the change purely structural — preserve runtime behavior exactly — and reduce the original file by **at least 200 lines** in the PR. Make one-file-per-PR changes only. Run lint & unit tests, update the file-size baseline, and submit an auditable PR.
This document is your operating manual. Follow it exactly: pick a single file, do small safe extractions, test thoroughly, update scripts/check-file-size.mjs baseline, and open a PR with supporting documentation.
This document is your operating manual. Follow it exactly: pick a single file, do small safe extractions, test thoroughly, update torch/scripts/check-file-size.mjs baseline, and open a PR with supporting documentation.
-------------------------------------------------------------------------------
HIGH-LEVEL RULES & SAFETY
- **Target branch:** `<default-branch>`. Always operate against `<default-branch>`.
- **One file per PR only.** Do not decompose multiple files in one PR or one run.
- **Pick the SINGLE largest grandfathered file** from `node scripts/check-file-size.mjs --report` that **has not been decomposed recently**.
- **Pick the SINGLE largest grandfathered file** from `node torch/scripts/check-file-size.mjs --report` that **has not been decomposed recently**.
- “Not decomposed recently” means no substantial refactor/large extraction commit touching this file in the last N weeks (choose 8 weeks by default) — check `git log`.
- **Do not change behavior.** This is a pure extraction refactor. Tests and manual QA must pass.
- **Do not alter generated or vendored files.** Only source files under `js/`.
@@ -22,14 +22,14 @@ Create or update these artifacts and include them in your PR branch:
- `todo/TODO_<timestamp>.md` — checklist of extraction items (2–3 blocks) and status.
- `decisions/DECISIONS_<timestamp>.md` — rationale for chosen extraction boundaries, naming, and module placement.
- `test_logs/TEST_LOG_<timestamp>.md` — exact commands run with outputs (lint/tests/manual checks).
- `perf/decompose/` — optional helpers, raw `node scripts/check-file-size.mjs --report` output, and before/after line counts.
- `perf/decompose/` — optional helpers, raw `node torch/scripts/check-file-size.mjs --report` output, and before/after line counts.
-------------------------------------------------------------------------------
SELECTION PROCESS — how to pick the file
1. Run the file-size report:
```
node scripts/check-file-size.mjs --report | tee perf/decompose/raw-file-size-report-$(date +%F).log
node torch/scripts/check-file-size.mjs --report | tee perf/decompose/raw-file-size-report-$(date +%F).log
````
2. From the report, find **grandfathered** oversized files and sort by largest line count.
@@ -166,19 +166,19 @@ TESTING & VERIFICATION (mandatory)
---
UPDATE BASELINE (scripts/check-file-size.mjs)
UPDATE BASELINE (torch/scripts/check-file-size.mjs)
* After the refactor, run the file-size report again:
```
node scripts/check-file-size.mjs --report | tee perf/decompose/after-report-$(date +%F).log
node torch/scripts/check-file-size.mjs --report | tee perf/decompose/after-report-$(date +%F).log
```
* Run the update mode:
```
node scripts/check-file-size.mjs --update
node torch/scripts/check-file-size.mjs --update
```
* The script will print the new `BASELINE` object. **Copy the new `BASELINE`** into `scripts/check-file-size.mjs` (replace old baseline object).
* The script will print the new `BASELINE` object. **Copy the new `BASELINE`** into `torch/scripts/check-file-size.mjs` (replace old baseline object).
* Add a note to `decisions/DECISIONS_<timestamp>.md` explaining why the baseline changed (file reduced, new counts).
**Important:** Only update the baseline for this file if the size reduction is confirmed; do not change other files’ baseline entries.
@@ -219,7 +219,7 @@ ACCEPTANCE CRITERIA (must be true before merge)
* The original file is reduced by **at least 200 lines**.
* `npm run lint` passes.
* `npm run test:unit` passes.
* The updated `BASELINE` object in `scripts/check-file-size.mjs` reflects the new smaller size.
* The updated `BASELINE` object in `torch/scripts/check-file-size.mjs` reflects the new smaller size.
* No behavioral changes observed in smoke tests.
* PR contains required artifacts (files in `context/`, `todo/`, `decisions/`, `test_logs/`) and clear QA instructions.
@@ -249,14 +249,14 @@ FIRST-RUN CHECKLIST (execute now)
git checkout <default-branch>
git pull --ff-only
node -v && npm -v
node scripts/check-file-size.mjs --report | tee perf/decompose/raw-file-size-report.log
node torch/scripts/check-file-size.mjs --report | tee perf/decompose/raw-file-size-report.log
```
2. Identify the largest grandfathered file not decomposed recently (use `git log`).
3. Create branch `ai/decompose/<short-file-name>-v1`.
4. Read file, identify 2–3 cohesive blocks, document in `context/CONTEXT_<timestamp>.md` and `todo/TODO_<timestamp>.md`.
5. Extract blocks to new files, import in original file.
6. Run `npm run lint` and `npm run test:unit`. Fix issues.
7. Update `scripts/check-file-size.mjs` baseline via `--update`; copy new `BASELINE`.
7. Update `torch/scripts/check-file-size.mjs` baseline via `--update`; copy new `BASELINE`.
8. Commit, push, open PR with required artifacts and description.
---
+1 -1
View File
@@ -33,7 +33,7 @@ Create/update these files/folders (commit them in the branch when PRing):
- `todo/TODO_<timestamp>.md` — upgrade tasks and statuses.
- `decisions/DECISIONS_<timestamp>.md` — rationale for upgrade choices and tradeoffs.
- `test_logs/TEST_LOG_<timestamp>.md` — exact commands run and their outputs (timestamped).
- Optionally: `scripts/deps-audit.sh` for reproducible automation.
- Optionally: `torch/scripts/deps-audit.sh` for reproducible automation.
Also read `AGENTS.md` and `docs/KNOWN_ISSUES.md` for project-specific caveats (e.g., the repo uses `integration-tools`, `webtorrent`, `Playwright`, `Tailwind`). Tag these libraries for special handling.
@@ -7,7 +7,7 @@ This document is your operating manual. Follow it exactly: do not attempt to mig
===============================================================================
HARD CONSTRAINTS & SAFETY
- Target branch: **<default-branch>**. Do not modify other branches.
- Migrate **only ONE** file per PR. Choose a single file from `node scripts/check-innerhtml.mjs --report`.
- Migrate **only ONE** file per PR. Choose a single file from `node torch/scripts/check-innerhtml.mjs --report`.
- Do **not** change semantics. Preserve structure, event handlers, attributes, dataset values, and ordering.
- **Never** output user-supplied data as raw HTML. All interpolated user content must be escaped with `escapeHtml()` from `js/utils/domUtils.js`.
- Do **not** introduce new third-party libraries unless approved.
@@ -32,7 +32,7 @@ WORKFLOW — top-level steps (one file only)
- `node -v` and `npm -v` recorded in `context/CONTEXT_<timestamp>.md`
- Run the innerHTML report:
```
node scripts/check-innerhtml.mjs --report | tee perf/innerhtml/raw-report-$(date +%F).log
node torch/scripts/check-innerhtml.mjs --report | tee perf/innerhtml/raw-report-$(date +%F).log
```
- Inspect the report and **choose exactly one file** to migrate. Prefer:
- Files labeled `RISKY` in the audit (user data without escaping).
@@ -103,9 +103,9 @@ WORKFLOW — top-level steps (one file only)
7. **Update baseline**
- After verifying, update the baseline counts so the `check-innerhtml` script knows this file was addressed:
```
node scripts/check-innerhtml.mjs --update
node torch/scripts/check-innerhtml.mjs --update
```
- The script prints a new `BASELINE` object. **Copy** the updated `BASELINE` object into `scripts/check-innerhtml.mjs` (replace existing `BASELINE`).
- The script prints a new `BASELINE` object. **Copy** the updated `BASELINE` object into `torch/scripts/check-innerhtml.mjs` (replace existing `BASELINE`).
- Commit the updated script with a note in `decisions/DECISIONS_<timestamp>.md` explaining the baseline change.
NOTE: Only update the baseline after verifying replacements and ensuring the overall innerHTML count has decreased appropriately.
@@ -125,7 +125,7 @@ WORKFLOW — top-level steps (one file only)
- files in `context/`, `todo/`, `decisions/`, `test_logs/`
- A short summary of the file and changes:
- List of assignments replaced and strategy for each.
- Before/after innerHTML counts (run `node scripts/check-innerhtml.mjs --report` before and after and paste results).
- Before/after innerHTML counts (run `node torch/scripts/check-innerhtml.mjs --report` before and after and paste results).
- Lint and unit test results.
- Manual QA steps and results.
- Highlight any remaining `innerHTML` assignments intentionally left (with rationale).
@@ -229,8 +229,8 @@ ACCEPTANCE CRITERIA (before merging)
* The chosen file’s `innerHTML` assignments are replaced or documented; user data is escaped or DOM-built.
* Lint passes and unit tests pass locally and in CI.
* `scripts/check-innerhtml.mjs --report` shows reduced count for the chosen file.
* Updated `BASELINE` object copied into `scripts/check-innerhtml.mjs`.
* `torch/scripts/check-innerhtml.mjs --report` shows reduced count for the chosen file.
* Updated `BASELINE` object copied into `torch/scripts/check-innerhtml.mjs`.
* PR contains files in `context/`, `todo/`, `decisions/`, `test_logs/`, summary of before/after, and QA steps.
* Commit message prefix is `[security]`.
@@ -252,6 +252,6 @@ FINAL NOTES & Etiquette
Begin now:
1. Run `node scripts/check-innerhtml.mjs --report`
1. Run `node torch/scripts/check-innerhtml.mjs --report`
2. Pick **ONE** file (RISKY/high-count preferred).
3. Follow the workflow above and open a `[security]` PR to `<default-branch>` when ready.
+4 -4
View File
@@ -17,7 +17,7 @@ policy and open an issue rather than improvising.
SCOPE
In scope:
- Creating/maintaining a load test script under `scripts/agent/` (only if that
- Creating/maintaining a load test script under `torch/scripts/agent/` (only if that
directory exists in repo; verify first).
- Simulating many clients connecting to a relay and publishing configurable
mixes of events at configurable rates.
@@ -87,12 +87,12 @@ WORKFLOW
- existing event schema builders (e.g., integration event schema utilities)
- existing relay interaction clients/helpers
- docs describing playback fallback and relay write safety
- Confirm whether `scripts/agent/` and `artifacts/` are established patterns.
- Confirm whether `torch/scripts/agent/` and `artifacts/` are established patterns.
If not, do not invent directory conventions—open an issue proposing layout.
2) Implement load harness (minimal, configurable)
Target file (only if verified appropriate in repo):
- `scripts/agent/load-test.mjs`
- `torch/scripts/agent/load-test.mjs`
The harness must support configuration via env vars and/or CLI flags:
- `RELAY_URL` (required)
@@ -184,7 +184,7 @@ Open an issue instead of proceeding when:
───────────────────────────────────────────────────────────────────────────────
OUTPUTS PER RUN
- `scripts/agent/load-test.mjs` (or repo-approved equivalent)
- `torch/scripts/agent/load-test.mjs` (or repo-approved equivalent)
- A load report (JSON) produced locally (and committed only if repo allows)
- A prioritized list of bottlenecks tied to measured evidence
- 0–N issues for non-trivial bottlenecks, especially security-sensitive ones
@@ -83,8 +83,8 @@ WORKFLOW
- inspect repo for the correct serve path and update README or open an issue.
3) Implement a Playwright capture script
- Create (only if `scripts/agent/` exists or is repo convention; verify first):
- `scripts/agent/debug_frontend.py`
- Create (only if `torch/scripts/agent/` exists or is repo convention; verify first):
- `torch/scripts/agent/debug_frontend.py`
- The script must:
- open `http://localhost:8000`
- collect and print:
@@ -102,7 +102,7 @@ WORKFLOW
4) Run capture and identify the first blocker
- Run:
- `python3 scripts/agent/debug_frontend.py | tee artifacts/debug_frontend.log`
- `python3 torch/scripts/agent/debug_frontend.py | tee artifacts/debug_frontend.log`
- Diagnose the earliest blocking error:
- first `pageerror` OR first `console:error` that prevents initialization
- Extract:
@@ -126,7 +126,7 @@ WORKFLOW
- `npm run lint`
- `npm run test:unit`
- Re-run:
- `python3 scripts/agent/debug_frontend.py | tee artifacts/debug_frontend.log`
- `python3 torch/scripts/agent/debug_frontend.py | tee artifacts/debug_frontend.log`
- Confirm:
- the original blocking error is gone
- no new initialization-blocking error was introduced
@@ -162,7 +162,7 @@ Issue must include:
───────────────────────────────────────────────────────────────────────────────
OUTPUTS PER RUN
- `scripts/agent/debug_frontend.py` (if repo conventions allow)
- `torch/scripts/agent/debug_frontend.py` (if repo conventions allow)
- `artifacts/debug_frontend.log` (committed only if repo norms allow; otherwise excerpt in PR)
- 0–1 PR fixing the first initialization-blocking console/page error
- 0–N issues for unsafe/ambiguous follow-ups
+5 -5
View File
@@ -80,9 +80,9 @@ WORKFLOW
1) Preflight
- Read `AGENTS.md` and `CLAUDE.md` for:
- security constraints (crypto, key handling, relay policy)
- conventions for `scripts/agent/`, `examples/`, and artifacts
- conventions for `torch/scripts/agent/`, `examples/`, and artifacts
- Confirm whether these directories exist and are used in repo:
- `scripts/agent/`
- `torch/scripts/agent/`
- `examples/reproducers/`
- `artifacts/`
If not present, do not invent structure—open an issue proposing where fuzz
@@ -102,8 +102,8 @@ WORKFLOW
- unhandled exception from invalid inputs
3) Implement the fuzz harness
File naming (only if `scripts/agent/` is valid in repo):
- `scripts/agent/fuzz-<target>.mjs`
File naming (only if `torch/scripts/agent/` is valid in repo):
- `torch/scripts/agent/fuzz-<target>.mjs`
Harness requirements:
- Inputs: randomized cases covering:
@@ -205,7 +205,7 @@ Issue must include:
───────────────────────────────────────────────────────────────────────────────
OUTPUTS PER RUN
- `scripts/agent/fuzz-<target>.mjs` (if repo conventions allow)
- `torch/scripts/agent/fuzz-<target>.mjs` (if repo conventions allow)
- 0–N reproducers under `examples/reproducers/` (if allowed)
- `artifacts/fuzz-report-<target>-YYYYMMDD.json` (committed only if allowed)
- 0–1 PR (harness + repros, optionally small safe guards/tests)
+4 -4
View File
@@ -17,7 +17,7 @@ If a higher-level policy or doc conflicts with this prompt, follow the higher-le
SCOPE
In scope:
- Implement a small smoke-test harness at `scripts/agent/smoke-test.mjs` (or `.ts`/`.py` if repo prefers), exercising:
- Implement a small smoke-test harness at `torch/scripts/agent/smoke-test.mjs` (or `.ts`/`.py` if repo prefers), exercising:
- app start/serve (per README)
- headless browser/client run (Playwright preferred if available)
- sharedClient connection to a local/test relay
@@ -73,7 +73,7 @@ PREPARATION (preflight)
WORKFLOW (implementation & run steps)
1) Create harness file
- Path: `scripts/agent/smoke-test.mjs`
- Path: `torch/scripts/agent/smoke-test.mjs`
- Language: follow repo conventions (Node/Playwright preferred). If Playwright is used, the harness should run headless.
- CLI/ENV options:
- `--relays` or `RELAY_URLS` (csv) — **required**
@@ -149,11 +149,11 @@ EXAMPLE RUN
```bash
# conservative default (local test relay)
RELAY_URLS="ws://localhost:8080" node scripts/agent/smoke-test.mjs \
RELAY_URLS="ws://localhost:8080" node torch/scripts/agent/smoke-test.mjs \
--serve=npx --timeout=30 --burst=1 --out=artifacts/
# public relays only with explicit confirmation and extreme throttle
RELAY_URLS="wss://relay.example" node scripts/agent/smoke-test.mjs \
RELAY_URLS="wss://relay.example" node torch/scripts/agent/smoke-test.mjs \
--confirm-public --burst=1 --timeout=30 --out=artifacts/
```