# Node.js Wrapper API

`hil-node/hil.js` wraps the headless monitor. It spawns
`hil-orchestrator.exe -ipc -port <port>` and exposes an `EventEmitter`-based,
promise-backed API.

```js
const HIL_OS = require('./hil-node/hil.js');
```

## `new HIL_OS(goBinaryPath?)`

`goBinaryPath` defaults to `../bin/hil-orchestrator.exe`. Point it
at the monitor binary if it lives elsewhere.

## `async connect(port = 'auto', baud = 9600)`

Spawns the monitor in IPC mode. Resolves once the `ready` message arrives.
Rejects on child-process errors or if the engine does not report ready within
10 seconds. Use `port = 'none'` for pure headless operation (no hardware).

```js
const hil = new HIL_OS();
await hil.connect('none', 9600);
```

## `execute(lispScript)`

Streams a LISP script into the engine. Scripts keep their newlines (so `;`
comments work) and are terminated with `__HIL_END__`. Throws if not connected.

```js
hil.execute('(LOG "hello") (SET x (+ 1 2))');
```

## `shutdown()`

Terminates the Go engine process.

## Events

| Event | Payload | When |
|-------|---------|------|
| `ready` | (resolves connect) | Engine reports connected |
| `idle` | — | `execution_complete` — script finished |
| `interrupt` | `{ pin, value }` | Native hardware event (`EVT:` / `EVT_A:`) |
| `log` | raw `[LOG]` line | `LOG` output from the engine |
| `error` | string | Engine stderr or errors |
| `disconnect` | message | Engine exited |

```js
hil.on('log', line => console.log(line));
hil.on('interrupt', ({ pin, value }) => console.log(`pin ${pin} = ${value}`));
hil.on('idle', () => hil.shutdown());
```

## Example

```js
const HIL_OS = require('./hil-node/hil.js');

(async () => {
  const hil = new HIL_OS();
  hil.on('log', l => console.log(l));
  hil.on('idle', () => hil.shutdown());
  await hil.connect('none', 9600);
  hil.execute(`
    (SET n 0)
    (WHILE (< n 3)
      (DO (LOG "n=" n) (SET n (+ n 1))))
    (LOG "done")
  `);
})();
```
