# CLI

> The sollar command — scaffold, run, build, validate, sign, upload, submit, release and diagnose.

Source: https://miniapp.sollar.com/reference/cli/

---

```sh
npm install -g @sollar/cli
sollar --version
```

The CLI is **headless by design**. Every command that a release depends on runs without a GUI, so
continuous integration never needs a desktop IDE installed. This is a deliberate correction of the
most common complaint about WeChat's `miniprogram-ci`, where the compiler lived inside the IDE and
CI had to work around it.

## Commands

| Command | Does |
|---|---|
| `sollar init` | Adds Sollar scaffolding to an existing project |
| `sollar create-mini-app <name>` | New project from a template |
| `sollar dev` | Local dev server with hot reload |
| `sollar validate` | Validates the manifest and the project against the submission gate |
| `sollar build` | Produces the `.sapp` package |
| `sollar sign` | Adds the signature block |
| `sollar preview` | Opens the built package on your device via QR code |
| `sollar upload` | Uploads a development or trial version |
| `sollar submit` | Submits for review (store) or publishes (tenant-private) |
| `sollar release` | Publishes an approved version |
| `sollar rollback` | Republishes a previous build as a new version |
| `sollar logs` | Streams runtime logs from trial installs |
| `sollar doctor` | Diagnoses the environment |

### `sollar create-mini-app`

```sh
sollar create-mini-app acme-erp --template react
```

Templates: `vanilla` (default), `react`, `vue`, `svelte`. All are plain Vite projects — the runtime
*is* the web platform, so there is no proprietary dialect to compile into and no framework you are
obliged to use.

The scaffold includes `sollar.d.ts`, a validated `manifest.json`, an `AGENTS.md`, and a `CLAUDE.md`
that imports it. See [Build with AI](/ai/).

### `sollar dev`

```sh
sollar dev --port 4321 --tenant acme-corp-test
```

Serves the mini app at its synthetic origin — the same `https://<appid>.miniapp.localhost/` the
device uses — so origin-dependent behaviour matches production from the first run. Reloads the page
on source changes; a manifest change restarts the runtime, because permissions and the network
allowlist are read at launch.

Chrome DevTools and Safari Web Inspector attach normally. Sollar does not ship a debugger, because
the platform is the web and you already have two good ones.

### `sollar validate`

```sh
sollar validate            # manifest + project
sollar validate --strict   # also applies store-review checks
```

Checks the manifest against the published schema, verifies every declared action has a handler,
verifies every requested scope is declared, checks the CSP floor, and rejects bare IP addresses in
the network allowlist.

`--strict` adds the review checks: purpose strings that plausibly match the declared function,
justifiable network hosts, an SBOM with no high-severity findings, no remote scripts, no `eval`.

Run it in CI. A validation failure at submission has already cost you a round trip.

### `sollar build`

```sh
sollar build --sbom --mode production
```

| Flag | Effect |
|---|---|
| `--sbom` | Emits `sbom.cdx.json` (CycloneDX 1.7). Required for the store channel. |
| `--mode` | `development` \| `production` |
| `--out` | Output directory (default `dist/`) |
| `--delta-from <version>` | Also produces a patch against that version |

### `sollar sign`

```sh
sollar sign --key op://Personal/sollar-signing/private-key
sollar sign --keyless
```

> **DANGER**
`--key` takes a **reference**, never a key. The CLI resolves it at the moment of signing and never
writes key material to disk. A literal path to a private key file is refused.

`--keyless` uses Sigstore: an ephemeral key bound to an OIDC identity, with a transparency-log
record. Nothing to store, and therefore nothing to leak. Recommended for CI.

### `sollar submit`

```sh
sollar submit --tenant acme-corp          # tenant-private: publishes, no review
sollar submit                             # store: enters the review queue
sollar submit --notes "Fixes the expense export."
```

For the store channel, only one version can be in review at a time. Submitting again **replaces**
the queued version rather than queueing behind it.

### `sollar release`

```sh
sollar release --version 2.4.1
sollar release --version 2.4.1 --phased
```

Approval and publication are separate steps: review approves, you decide when it goes live. An
approval that is never released expires after 30 days.

`--phased` follows a fixed curve — **1%, 2%, 5%, 10%, 20%, 50%, 100%**, one step per day, pausable
at any point. The curve is fixed rather than freely chosen on purpose: nobody picks a good
percentage at three in the morning with the error graph climbing.

### `sollar rollback`

```sh
sollar rollback --to 2.4.0
```

Republishes the 2.4.0 build as **2.4.2**. It is not a reversal — monotonic versions are what let a
client know it needs to update, and lowering a version number destroys that guarantee.

No review, because the code was already reviewed. Publishing never-reviewed code through this path
is abuse, and the platform detects it by comparing hashes against approved versions.

### `sollar doctor`

```sh
sollar doctor
```

Checks the Node version, CLI version, bridge type definitions, manifest validity, signing-key
reachability, and connectivity to the test organisation. Run it first when something is wrong.

## Configuration

Split in two, and this split matters:

```json title="sollar.config.json — committed"
{
  "manifest": "./manifest.json",
  "root": "./src",
  "out": "./dist",
  "build": { "target": "es2022", "sbom": true }
}
```

```json title=".sollar/local.json — gitignored"
{
  "tenant": "acme-corp-test",
  "device": "iphone-15-pro",
  "signing_key_ref": "op://Personal/sollar-signing/private-key"
}
```

Shared build configuration is versioned; per-machine preference is not. WeChat's
`project.config.json` mixes the two, and the result is a file that produces a diff every time a
different developer opens the project.

`.sollar/local.json` holds only *references* to secrets, never secrets.

## Continuous integration

```yaml title=".github/workflows/release.yml"
- run: npm ci
- run: npx sollar validate --strict
- run: npx sollar build --sbom
- run: npx sollar sign --keyless
- run: npx sollar submit --tenant acme-corp
```

No GUI, no desktop IDE, no key in a repository variable.
