Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,64 @@ The shortest way to spot a missing step: TypeScript compile errors
in `web/src/` that say "Module ... has no exported member ...". That
means the SDK is stale.

## Never overwrite `apps/temps-cli/openapi.json` with the raw server response

The CLI's SDK is generated from a **committed** copy of the spec at
`apps/temps-cli/openapi.json`. That file is ~92,000 lines of formatted
JSON; the server serves the same document minified on one line, with
keys in whatever order serde produced.

So `curl .../openapi.json > apps/temps-cli/openapi.json` turns a
92,000-line file into a 1-line file, and the pull request reports
**-92,000 deletions** — burying the actual change and making the diff
unreviewable. Pretty-printing alone is not enough either: key order is
not stable between builds, so an unsorted dump reorders huge blocks for
no reason.

Use the script, which fetches, sorts keys recursively, indents by two
and keeps the trailing newline:

```bash
cd apps/temps-cli
TEMPS_API_KEY=tk_... bun run spec:update --url http://localhost:8080/api/api-docs/openapi.json
bun run generate:api # regenerate the client from the file
bun run scripts/generate-docs.ts --output docs/CLI.md
bun run scripts/generate-docs.ts --format mdx --output docs/CLI.mdx
```

Sanity check before committing — a few new endpoints should be a few
hundred changed lines, never tens of thousands:

```bash
git diff --numstat -- apps/temps-cli/openapi.json
```

`web/src/api/client/` has no committed spec; it is generated straight
from the live server by `bun run openapi-ts` (see above), so it does not
have this failure mode.

## Resolving merge conflicts in generated clients

Conflicts in `web/src/api/client/**`, `apps/temps-cli/src/api/**` or
`apps/temps-cli/openapi.json` are conflicts in **build output**. Do not
hand-merge them, and do not hand-pick hunks — the result is a client
that matches neither side's spec.

Take either side to clear the conflict, then regenerate from a server
built off the merged source:

```bash
git checkout --ours -- web/src/api/client apps/temps-cli/src/api apps/temps-cli/openapi.json
git add web/src/api/client apps/temps-cli/src/api apps/temps-cli/openapi.json
# build + start the merged server, then:
cd apps/temps-cli && bun run spec:update --url <server>/api/api-docs/openapi.json && bun run generate:api
cd ../../web && bun run openapi-ts
```

Then `bun run typecheck` (or `npx tsc --noEmit`) in both `web/` and
`apps/temps-cli/`. A clean typecheck is what proves the regenerated
client still satisfies every caller on both sides of the merge.

## Scope Docker usage on shared hosts

This host may already be running a live Temps instance or other
Expand Down
31 changes: 31 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Guidance for Claude Code when working with the Temps codebase.
- Leave the project in non-compilable state
- Use `#[tokio::main]` when integrating with pingora
- Use plain text logging -- ALWAYS use structured JSONL logging
- Overwrite `apps/temps-cli/openapi.json` with the raw server response (`curl ... > openapi.json`) -- the committed file is ~92,000 lines of sorted, indented JSON and the server serves it minified on one line, so a direct write reports **-92,000 deletions** and buries the real change. ALWAYS use `cd apps/temps-cli && bun run spec:update` (see [Regenerating the OpenAPI clients](#regenerating-the-openapi-clients))
- Create markdown documentation files unless explicitly requested
- Mark Docker tests with `#[ignore]` -- they MUST skip gracefully at runtime instead
- Create error types with generic messages -- ALWAYS include IDs, names, and operation context
Expand Down Expand Up @@ -731,6 +732,36 @@ async fn create_backup(
- Convert entities to response DTOs via `From` trait
- Register all handlers in `ApiDoc` with `#[openapi(...)]`

### Regenerating the OpenAPI clients

Two generated clients consume the spec, and they are refreshed differently:

| Client | Source of truth | Refresh with |
|---|---|---|
| `web/src/api/client/` | the **live server** | `cd web && bun run openapi-ts` |
| `apps/temps-cli/src/api/` | the **committed** `apps/temps-cli/openapi.json` | `cd apps/temps-cli && bun run spec:update && bun run generate:api` |

After any change to handlers, request/response shapes, schemas or routes:
restart `temps serve`, then refresh both. Commit the regenerated files --
they are tracked so reviewers see the API delta.

`apps/temps-cli/openapi.json` must stay in its canonical shape: **keys sorted
recursively, two-space indent, trailing newline**. `bun run spec:update` is the
only supported way to write it. Sorting is what keeps a diff proportional to
the API change instead of to serde's iteration order, which is not stable
between builds.

Verify before committing -- adding a few endpoints is a few hundred changed
lines, never tens of thousands:

```bash
git diff --numstat -- apps/temps-cli/openapi.json
```

Merge conflicts in either client are conflicts in build output. Never
hand-merge them: take one side to clear the conflict, then regenerate from a
server built off the merged source and typecheck both packages.

### Permission System

```rust
Expand Down
111 changes: 109 additions & 2 deletions apps/temps-cli/docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Auto-generated documentation for the Temps CLI.
>
> Generated on: 2026-08-04
> Generated on: 2026-08-07

## Installation

Expand Down Expand Up @@ -235,6 +235,20 @@ Delete a project
| `-f, --force` | Skip confirmation | - | No |
| `-y, --yes` | Skip confirmation (alias for --force) | - | No |

## `drop`

Detect and deploy a local source directory or ZIP without Git

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--name <name>` | Project name (slugified automatically) | - | Yes |
| `--preset <preset>` | Select a detected preset | - | Yes |
| `--directory <directory>` | Select a detected project root | - | Yes |
| `--no-wait` | Do not wait for deployment to complete | - | No |
| `--timeout <seconds>` | Deployment timeout | `600` | Yes |

## `deploy`

Deploy a project from git
Expand Down Expand Up @@ -695,7 +709,7 @@ Set an environment variable
| `-e, --environments <names>` | Comma-separated environment names (interactive if not provided) | - | Yes |
| `--no-preview` | Exclude from preview environments | - | No |
| `--update` | Update existing variable instead of creating new | - | No |
| `--secret` | Store as a secret: the value is masked in the UI and never returned by the API. One-way — a secret cannot later be made non-secret | - | No |
| `--secret` | Store as a secret: the value is masked in the UI and never returned by the API. One-way — to make a secret readable again you must delete the variable and create it anew | - | No |

#### `environments vars delete` (alias: `rm`, `unset`)

Expand Down Expand Up @@ -1973,6 +1987,99 @@ Set the preview domain pattern
|------|-------------|---------|----------|
| `--domain <domain>` | Preview domain pattern | - | Yes |

## `platform` (alias: `plat`)

View platform and server information

**Subcommands:**

- `info` - Get platform information
- `access` - Get access and networking information
- `private-ip` - Get the server private IP address
- `public-ip` - Get the server public IP address
- `update` - Check for and apply temps releases on the server

### `platform info`

Get platform information

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

### `platform access`

Get access and networking information

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

### `platform private-ip`

Get the server private IP address

### `platform public-ip`

Get the server public IP address

### `platform update`

Check for and apply temps releases on the server

**Subcommands:**

- `status` - Show the available release and whether it can be applied from here
- `check` - Ask the release API for the newest version on this channel now
- `channel` - Show or set the release channel: stable, beta, nightly, or "auto" to follow the installed version
- `apply` - Install a release on the server and restart it

#### `platform update status`

Show the available release and whether it can be applied from here

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

#### `platform update check`

Ask the release API for the newest version on this channel now

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

#### `platform update channel`

Show or set the release channel: stable, beta, nightly, or "auto" to follow the installed version

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

#### `platform update apply`

Install a release on the server and restart it

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--version <version>` | Release tag to install (default: newest on this channel) | - | Yes |
| `-y, --yes` | Skip the confirmation prompt | - | No |
| `--json` | Output in JSON format | - | No |

## `users`

Manage platform users
Expand Down
111 changes: 109 additions & 2 deletions apps/temps-cli/docs/CLI.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const metadata = {

> Auto-generated documentation for the Temps CLI.
>
> Generated on: 2026-08-04
> Generated on: 2026-08-07

## Installation

Expand Down Expand Up @@ -240,6 +240,20 @@ Delete a project
| `-f, --force` | Skip confirmation | - | No |
| `-y, --yes` | Skip confirmation (alias for --force) | - | No |

## `drop`

Detect and deploy a local source directory or ZIP without Git

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--name <name>` | Project name (slugified automatically) | - | Yes |
| `--preset <preset>` | Select a detected preset | - | Yes |
| `--directory <directory>` | Select a detected project root | - | Yes |
| `--no-wait` | Do not wait for deployment to complete | - | No |
| `--timeout <seconds>` | Deployment timeout | `600` | Yes |

## `deploy`

Deploy a project from git
Expand Down Expand Up @@ -700,7 +714,7 @@ Set an environment variable
| `-e, --environments <names>` | Comma-separated environment names (interactive if not provided) | - | Yes |
| `--no-preview` | Exclude from preview environments | - | No |
| `--update` | Update existing variable instead of creating new | - | No |
| `--secret` | Store as a secret: the value is masked in the UI and never returned by the API. One-way — a secret cannot later be made non-secret | - | No |
| `--secret` | Store as a secret: the value is masked in the UI and never returned by the API. One-way — to make a secret readable again you must delete the variable and create it anew | - | No |

#### `environments vars delete` (alias: `rm`, `unset`)

Expand Down Expand Up @@ -1978,6 +1992,99 @@ Set the preview domain pattern
|------|-------------|---------|----------|
| `--domain <domain>` | Preview domain pattern | - | Yes |

## `platform` (alias: `plat`)

View platform and server information

**Subcommands:**

- `info` - Get platform information
- `access` - Get access and networking information
- `private-ip` - Get the server private IP address
- `public-ip` - Get the server public IP address
- `update` - Check for and apply temps releases on the server

### `platform info`

Get platform information

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

### `platform access`

Get access and networking information

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

### `platform private-ip`

Get the server private IP address

### `platform public-ip`

Get the server public IP address

### `platform update`

Check for and apply temps releases on the server

**Subcommands:**

- `status` - Show the available release and whether it can be applied from here
- `check` - Ask the release API for the newest version on this channel now
- `channel` - Show or set the release channel: stable, beta, nightly, or "auto" to follow the installed version
- `apply` - Install a release on the server and restart it

#### `platform update status`

Show the available release and whether it can be applied from here

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

#### `platform update check`

Ask the release API for the newest version on this channel now

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

#### `platform update channel`

Show or set the release channel: stable, beta, nightly, or "auto" to follow the installed version

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--json` | Output in JSON format | - | No |

#### `platform update apply`

Install a release on the server and restart it

**Options:**

| Flag | Description | Default | Required |
|------|-------------|---------|----------|
| `--version <version>` | Release tag to install (default: newest on this channel) | - | Yes |
| `-y, --yes` | Skip the confirmation prompt | - | No |
| `--json` | Output in JSON format | - | No |

## `users`

Manage platform users
Expand Down
Loading