
# CLI

Phasis ships three main executables in `bin/`:

- **`bin/phasis`** — run JavaScript files, evaluate source passed on the command line, dump ASTs.
- **`bin/test262`** — run the official ECMAScript conformance suite against Phasis.
- **`bin/wpt`** — run the Web Platform Tests fixtures against Phasis (URL, encoding, fetch, headers, Blob, AbortSignal, streams, …).

After `composer require phasis/phasis`, `bin/phasis` and `bin/test262` are linked from `vendor/bin/`. Only `bin/phasis` works from there: `bin/test262` needs the `test262` git submodule and the test classes, which the Composer package does not include, and `bin/wpt` is not shipped at all. Run both from a clone of the Phasis repository.

## bin/phasis

```
phasis <file.js> | phasis -e '<source>' | phasis --ast <file.js>
```

These three forms are the whole interface. There is no REPL, no stdin input and no module flag.

### Run a file

```bash
./vendor/bin/phasis script.js
```

Executes `script.js` as a classic script. When it finishes, everything the script wrote with `console.log` (and `console.error`, `console.warn`, …) is printed to stdout in one go. If the script throws, the error message goes to stderr and the exit status is 1.

The file is always parsed as a classic script, so a file with `import` / `export` or top-level `await` fails with a SyntaxError. To run an ES module, use `Engine::evalAsModule()` from PHP (see the [API reference](/docs/api#evalasmodule)) or bundle the code first.

### Evaluate source

```bash
./vendor/bin/phasis -e 'console.log(Math.PI * 2)'
# 6.283185307179586
```

The argument is evaluated as a complete script. Only `console` output is printed; the value of the last expression is not, so `phasis -e '1 + 2'` prints nothing.

### Dump the AST

```bash
./vendor/bin/phasis --ast script.js
./vendor/bin/phasis -e 'a + b' --ast
```

Prints the parse tree as JSON (indented by two spaces). Useful for debugging parser issues or building tooling on top of Phasis. For programmatic access, use the [parser API](/docs/parser).

## bin/test262

`bin/test262` runs the [official test262 suite](https://github.com/tc39/test262) against Phasis. It's useful as a regression harness when contributing changes. The full-suite snapshot in `COMPAT.md` is produced by the related `bin/compat-report`, which the manually started CI matrix runs in shards.

### Run a single category

```bash
./bin/test262 --category built-ins/Array
```

### Run the full suite

```bash
./bin/test262 --jobs 4
```

### Configuration

The runner reads `config/support.php` from the project root. Its `test262_skipped_features` list is empty: no test262 feature is skipped, including `tail-call-optimization`. The file also lists the categories and the tests that must run in isolation.

The suite itself is the `test262` git submodule; run `git submodule update --init test262` after cloning. Without it the runner exits with "test262 suite not found".

### Other useful flags

| Flag | Purpose |
|---|---|
| `--failures` | print one line per failing test |
| `--limit N` | stop after the first N tests |
| `--jobs N` | run N tests in parallel |
| `--files-from file` | run only the tests listed in `file` |
| `--json` | emit machine-readable summary on stdout |
| `--no-progress` | suppress the progress line |

See the [Compatibility section](/docs/compatibility) for the latest snapshot.

## bin/wpt

`bin/wpt` runs the Web Platform Tests fixtures imported into `tests/Wpt/fixtures/`. The corpus covers URL, encoding, atob/btoa, structuredClone, performance, Headers, Blob/File, AbortController/Signal, EventTarget, FormData, WHATWG Streams, the full `crypto`/`SubtleCrypto` surface, `fetch`/`Request`/`Response`, `XMLHttpRequest`/`XMLHttpRequestUpload`, and `WebSocket`. See [Web APIs](/docs/compatibility/web-apis) for the per-area pass-rate table.

### Run all imported fixtures

```bash
./bin/wpt
```

### Run one category

```bash
./bin/wpt --category headers
./bin/wpt --category streams
./bin/wpt --category blob
```

### Per-subtest output

```bash
./bin/wpt --category abort --verbose
```

Prints every subtest (PASS / FAIL) inside each fixture, with assertion messages on failures.

### JSON output

```bash
./bin/wpt --json
```

Machine-readable pass/fail summary for CI pipelines or scripted analysis.

### Notes

- Fetch-touching fixtures auto-start the bundled WPT test server at `tests/Wpt/fetch-server.php` on `127.0.0.1:8765` and tear it down afterwards.
- The harness shim at `tests/Wpt/testharness-shim.js` implements just the WPT API surface the imported fixtures use (~400 lines vs the full ~3K-line `testharness.js`).
- Source fixtures live at `tests/Wpt/upstream/` (a gitignored sparse-checkout of [web-platform-tests/wpt](https://github.com/web-platform-tests/wpt)). To import more, copy `.any.js` files from `upstream/<area>/` into `fixtures/<category>/` and the runner picks them up automatically.

## Exit codes

`bin/phasis` exits with one of two codes:

| Code | Meaning |
|---|---|
| `0` | success — the script ran to completion (also after `--ast`) |
| `1` | anything else: an uncaught JS exception, a syntax error, a missing file or invalid arguments |

Errors from the script print their message to stderr. Invalid arguments and missing files print the usage line to stderr.

## Resource limits

`bin/phasis` runs with the engine defaults and has no flags for limits: a 4,096-frame JS call-stack ceiling, an 8,192-frame guard for transpiled closures, and the default `maxLoopIterations` of 100,000, which only applies to code the tree-walking interpreter runs (see [API: setLimit](/docs/api#setlimit)). There is no time limit; wrap the command in `timeout` if a script may not terminate.
