# WEB CLI

The WEB CLI has four jobs:

- initialize a new WEB project in the current directory or one target directory
- compile `.web` source files into matching HTML and CSS files
- render a compiled `.web` page to a screenshot image
- watch one `.web` source and rebuild it automatically on change

The command is exposed as:

```bash
web
```

This package exposes the CLI binary from `bin/web.js`.

## Quick Start

Initialize a starter project in a clean directory:

```bash
web init
```

Initialize the current directory explicitly:

```bash
web init .
```

Initialize a new `website` folder and create it if it does not exist yet:

```bash
web init website
```

Compile a single file:

```bash
web home.web
```

Compile the same file without writing the extension:

```bash
web home
```

Compile every `.web` file in the current directory:

```bash
web .
```

Compile matching files from another directory:

```bash
web ./code/*
```

Render a screenshot using the default full-page mode:

```bash
web screenshot home.web
```

Render a JPG at a specific viewport size and device scale factor:

```bash
web screenshot home.web --jpg 1080 1080 2
```

Watch a file and recompile it automatically:

```bash
web watch home.web
```

Watch a file and capture a baseline screenshot plus timed snapshots every 5 minutes:

```bash
web watch home.web -s
```

If no argument is provided and `layout.web` exists in the current working directory, the CLI compiles `layout.web` automatically.

When `web init` runs, the CLI also creates `web-lang-agents.md` in the chosen project root by combining `getting-started.md`, `cli.md`, and `compiler.md` in that order. The goal is to give local agents one up-to-date context document to load quickly.

## Installation and Invocation

From this repo, the command is registered in `package.json` as:

```json
{
  "bin": {
    "web": "./bin/web.js"
  }
}
```

Common ways to run it during development:

```bash
node bin/web.js init
```

```bash
node bin/web.js init website
```

```bash
npm link
web init
```

```bash
npm link
web init website
```

```bash
node bin/web.js home.web
```

```bash
npm link
web home.web
```

```bash
npm link
web screenshot home.web
```

```bash
npm link
web watch home.web -s
```

## Commands

### 1. Init

The init command scaffolds a starter WEB project in the current working directory or in one target directory, generates a local agent context document, and compiles the starter page immediately.

Basic form:

```bash
web init
```

```bash
web init .
```

```bash
web init website
```

Behavior:

- Uses the current working directory when you omit the target.
- Accepts one directory target such as `.` or `website`.
- Creates the target directory automatically when it does not exist yet.
- Creates `index.web` with a simple intro banner.
- Creates `web-lang-agents.md` by combining `getting-started.md`, `cli.md`, and `compiler.md` from the packaged docs.
- Compiles the starter page into `index.html` and `index.css`.
- Refuses to overwrite existing `index.web`, `index.html`, `index.css`, or `web-lang-agents.md` files in the target directory.

Example:

```bash
web init .
```

```bash
web init website
```

Notes:

- Run `web init` against a clean target directory.
- The generated `web-lang-agents.md` is meant for local agent context, not browser output.
- After `web init`, you can keep working in `index.web` or replace it with your own page structure.
- If the target directory already exists, WEB scaffolds inside it instead of creating a nested project name automatically.

### 2. Compile

These forms all route through the compile command even when you do not write `compile` explicitly.

The following are equivalent:

```bash
web home.web
```

```bash
web compile home.web
```

### 3. Screenshot

The screenshot command compiles one `.web` source, writes the matching HTML and CSS outputs, then opens the compiled HTML in a headless browser and captures an image.

Basic form:

```bash
web screenshot home.web
```

Explicit JPG viewport capture:

```bash
web screenshot home.web --jpg 1080 1080 2
```

Syntax:

```bash
web screenshot <source> [--jpg|--png] [width height [deviceScaleFactor]]
```

Behavior:

- Accepts one resolved `.web` source at a time.
- Uses the same file and bare-name resolution rules as the compile command.
- Writes `home.html` and `home.css` next to the source file.
- Writes the screenshot image into `./web-lang-screenshots` rooted at the current working directory.
- Creates `./web-lang-screenshots` automatically when it does not exist yet.
- Appends a human-readable local timestamp to each screenshot filename.
- Uses `jpg` by default.
- If no width and height are provided, the command uses a `1600px` wide viewport, keeps the default device scale factor of `1`, and captures the full page.
- If width and height are provided, the command captures the current viewport instead of forcing `fullPage`.

Examples:

```bash
web screenshot home
```

```bash
web screenshot home.web --png 1440 900
```

```bash
web screenshot home.web --jpg 1080 1080 2
```

Notes:

- The first numeric argument is the viewport width.
- The second numeric argument is the viewport height.
- The optional third numeric argument is the browser `deviceScaleFactor`.
- A higher `deviceScaleFactor` produces a sharper image with more output pixels.

### 4. Watch

The watch command watches one resolved `.web` source, recompiles it when the source changes, and stays alive until the session is idle long enough to shut itself down.

Basic form:

```bash
web watch home.web
```

Watch with timed screenshots:

```bash
web watch home.web -s
```

Syntax:

```bash
web watch <source> [-screenshot|-s]
```

Behavior:

- Accepts exactly one resolved `.web` source.
- Uses the same file and bare-name resolution rules as the compile command.
- Performs an initial compile when the watch session starts.
- Recompiles the source whenever the watched file changes.
- Stops automatically after 1 hour with no recent source activity.
- Prints a verbose exit summary explaining why the watch session ended.
- With `-s` or `-screenshot`, captures one baseline screenshot after the first successful compile and then keeps capturing snapshots every 5 minutes.
- Uses the same `./web-lang-screenshots` workspace and timestamped filename pattern as `web screenshot`.

Examples:

```bash
web watch home
```

```bash
web watch home.web
```

```bash
web watch home.web -s
```

```bash
web watch home.web -screenshot
```

Notes:

- Watch mode currently supports one source file at a time.
- Periodic screenshots do not reset the idle timer.
- If the source file keeps changing, the watch session stays alive and keeps rebuilding.

## Compile Target Forms

### 1. Compile one explicit file

```bash
web landing.web
```

Behavior:

- Resolves the path relative to the current working directory.
- Accepts only files ending in `.web`.
- Writes outputs next to the source file.

Example result:

- `landing.web` -> `landing.html`
- `landing.web` -> `landing.css`

### 2. Compile one file by bare name

```bash
web landing
```

Behavior:

- If `landing.web` exists in the current working directory, it is used.
- This convenience only applies when the target has no extension.
- If the file does not exist, the CLI reports a target issue.

### 3. Compile a directory

```bash
web .
```

Behavior:

- Compiles direct `.web` files in that directory.
- Does not recurse into nested folders.
- Ignores non-`.web` files.

Example:

```text
project/
  home.web
  about.web
  notes.txt
  code/
    contact.web
```

`web .` compiles:

- `home.web`
- `about.web`

It does not compile:

- `notes.txt`
- `code/contact.web`

### 4. Compile a glob

```bash
web ./code/*
```

Behavior:

- Supports `*`, `?`, and character ranges like `[ab]`.
- Matches are resolved relative to the current working directory.
- Matching directories are expanded into direct `.web` files inside them.
- Matching files are compiled only if they end in `.web`.

Notes:

- In shells like `zsh`, the shell may expand the glob before the CLI receives it. That still works.
- If the shell does not expand the glob, the CLI expands it itself.

## Output Rules

The compile command writes outputs next to each source file using the same base name.

Examples:

- `home.web` -> `home.html` and `home.css`
- `pages/about.web` -> `pages/about.html` and `pages/about.css`
- `src/marketing/hero.web` -> `src/marketing/hero.html` and `src/marketing/hero.css`

The generated HTML links to the matching CSS filename for that source file.

The screenshot command writes image artifacts into a dedicated screenshot workspace rooted at the current working directory.

Examples:

- `home.web` -> `web-lang-screenshots/home-YYYY-MM-DD_HH-mm-ss-SSS.jpg`
- `home.web` with `--png` -> `web-lang-screenshots/home-YYYY-MM-DD_HH-mm-ss-SSS.png`
- `pages/about.web` -> `web-lang-screenshots/pages/about-YYYY-MM-DD_HH-mm-ss-SSS.jpg`

The command still writes `home.html` and `home.css` first, because the screenshot is taken from the compiled page.

When the source file lives inside the current working directory, the CLI preserves its relative folder structure inside `web-lang-screenshots` to avoid filename collisions.
If two captures happen with the same timestamp label, the CLI adds a numeric suffix instead of overwriting the earlier image.

The watch command uses the same screenshot workspace and filename pattern when `-s` or `-screenshot` is enabled.

## User Experience

### Header

At startup, the CLI prints a header with:

- the CLI name
- the current version
- the number of WEB sources being compiled
- the current working directory

### Progress display

For each compile step, the CLI shows progress like:

```text
[1/3] Compiling home.web
```

When stdout is attached to a TTY, this line is animated with a spinner while compilation is running.

When stdout is not a TTY, the CLI prints static progress lines instead of animation. This makes logs and CI output cleaner.

### Per-step success line

On success, the compile flow prints:

- input file
- output HTML path
- output CSS path
- compile duration

It also prints per-file stats:

- DOM node count
- CSS rule count
- head entry count
- script block count
- source size
- total output size

The screenshot flow adds a second render step and prints:

- screenshot image path
- render duration
- format
- viewport or full-page mode
- device scale factor
- image size in bytes

The watch flow prints:

- an initial watch header describing the watched file, idle timeout, and screenshot mode
- a compile step each time the watched file changes
- a screenshot step when the baseline capture or periodic snapshots run
- a verbose exit block when the session stops because there was no recent source activity

### Summary block

After the compile command finishes, the CLI prints totals for:

- succeeded files
- failed files
- skipped targets
- total source bytes
- total output bytes
- total DOM nodes
- total CSS rules
- total head entries
- total script blocks
- total duration

After the screenshot command finishes, the CLI prints a focused summary for the single capture:

- source path
- generated HTML path
- generated CSS path
- image path
- image format
- capture mode
- viewport size and device scale factor
- measured page size
- image bytes
- compile stats
- total duration

After the watch command finishes because of inactivity, the CLI prints:

- the shutdown reason
- the watched source
- the idle threshold that was reached
- the last observed source activity time
- the last successful compile time
- the last failed compile details, when present
- the number of successful builds
- the number of failed builds
- the number of screenshots captured, when screenshot mode was enabled
- the total elapsed watch-session time

## Help and Version

Show usage help:

```bash
web --help
```

or

```bash
web -h
```

Show the CLI version:

```bash
web --version
```

or

```bash
web -v
```

Show command-specific help:

```bash
web init --help
```

```bash
web screenshot --help
```

```bash
web compile --help
```

```bash
web watch --help
```

## Exit Behavior

The CLI exits with code `0` when all requested targets resolve cleanly and all compiles succeed.

The CLI exits with code `1` when:

- no input targets are available
- init arguments are invalid
- an init target resolves to a file instead of a directory
- init would overwrite existing scaffold files
- one or more targets cannot be resolved
- one or more compiles fail
- screenshot arguments are invalid
- screenshot rendering fails
- watch arguments are invalid
- an unexpected runtime error occurs

The watch command exits with code `0` when it stops normally due to inactivity after at least one successful build.

The watch command exits with code `1` when it never produces a successful build before the session ends.

## Target Resolution Details

Targets are collected, normalized, and deduplicated before compilation.

This means:

- passing the same file more than once still compiles it once
- files from multiple targets are merged into one compile set
- final compile order is sorted by path

For `web screenshot`, the resolved target set must contain exactly one `.web` source. If a glob or directory resolves to more than one file, the CLI stops and explains the mismatch instead of guessing.

For `web watch`, the resolved target set must also contain exactly one `.web` source.

Example:

```bash
web home.web . ./pages/*
```

If `home.web` is also included by `.` or `./pages/*`, it will still only compile once.

## Error Reporting

The CLI distinguishes between two kinds of problems:

### Target issues

These happen before compilation starts.

Examples:

- a path does not exist
- a glob matches no `.web` files
- a directory contains no `.web` files

These are reported under a `Target issues` section and count toward `Skipped` in the summary.

### Compile failures

These happen after a `.web` file is selected for compilation.

Examples:

- syntax errors
- semantic errors from the compiler
- unexpected worker failures

These are reported per file and count toward `Failed` in the summary.

## Relationship to `node compiler.js`

The CLI and the legacy script mode are intentionally different:

- `node compiler.js` reads `layout.web` and writes `index.html` plus `styles.css`
- `web home.web` reads `home.web` and writes `home.html` plus `home.css`

Use the CLI when you want arbitrary `.web` filenames or multi-file compilation.

## Current Limitations

The current CLI behavior is intentionally simple:

- `web init` accepts at most one directory target
- directory compilation is not recursive
- there are no custom output directory flags yet
- watch mode supports one `.web` source at a time
- watch screenshots always use the default screenshot render settings
- there are no quiet or JSON output modes yet

If those features are added later, this document should be updated alongside `bin/web.js`.
