Run prettier across the repo, exclude the lockfile from it
Prettier had never been run in --check mode here before, so this had drifted across most files (markdown tables, long option() chains, line wrapping). Purely formatting, no logic changes - needed so a CI format:check gate can actually pass. Adds .prettierignore for pnpm-lock.yaml specifically: prettier's YAML formatter rewrites every quoted key (single -> double quotes) producing an ~8700-line diff of pure noise on a file pnpm itself owns the formatting of. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -77,7 +77,7 @@ code). `404` if not found.
|
||||
|
||||
### `POST /api/runs/:runId/cancel`
|
||||
|
||||
`202 {"status": "cancelling"}`. `409` if the run already finished, or if it isn't tracked by *this*
|
||||
`202 {"status": "cancelling"}`. `409` if the run already finished, or if it isn't tracked by _this_
|
||||
server process (e.g. after a restart — see "orphaned runs" in `docs/ARCHITECTURE.md`).
|
||||
|
||||
### `GET /api/runs/:runId/logs`
|
||||
|
||||
@@ -46,8 +46,8 @@ straight from source, with no compile/bundle step for either.
|
||||
logic in `src/lib/runner/engine.ts` - it just calls it from a different position:
|
||||
|
||||
- If a server is reachable (`GET /api/healthz`), `run` is a plain HTTP+WS client: `POST
|
||||
/api/scripts/:id/runs` (the same route the web UI's "Run" button calls) starts the run *inside
|
||||
that server's process*, and `run` then subscribes over `/ws/runs` exactly like a browser tab
|
||||
/api/scripts/:id/runs` (the same route the web UI's "Run" button calls) starts the run _inside
|
||||
that server's process_, and `run` then subscribes over `/ws/runs` exactly like a browser tab
|
||||
would, using the same `ClientMessage`/`ServerMessage` protocol (`src/lib/ws/protocol.ts`). This
|
||||
is why a run started this way appears live in any open browser tab for free - the broadcast path
|
||||
(`emitRunMessage` → the `runEvents` listener in `src/lib/ws/server.ts` → every subscribed
|
||||
@@ -81,7 +81,7 @@ reimplemented.
|
||||
## Cross-module-graph state
|
||||
|
||||
Next compiles Route Handlers and Server Components through its own build/module graph, which is a
|
||||
*separate* module instantiation from whatever `server.ts` imports directly via `tsx` at startup —
|
||||
_separate_ module instantiation from whatever `server.ts` imports directly via `tsx` at startup —
|
||||
even though both run in the same OS process. A plain module-level singleton (e.g. `new Map()` at
|
||||
the top of a file) ends up duplicated, one copy per graph, which silently breaks anything that
|
||||
needs to be shared across that boundary (the WebSocket subscriber registry, the live-run-handle
|
||||
@@ -110,10 +110,10 @@ queued → running → succeeded | failed | cancelled | timed_out
|
||||
## Auth
|
||||
|
||||
- Session: `iron-session` — a stateless, encrypted+signed cookie (no session-store table).
|
||||
- Config is the source of truth for *who* is allowed in; `src/lib/auth/sync.ts` upserts config
|
||||
- Config is the source of truth for _who_ is allowed in; `src/lib/auth/sync.ts` upserts config
|
||||
users/tokens into SQLite on boot, giving a single DB-backed check path plus `lastLoginAt` tracking.
|
||||
- `src/proxy.ts` (Next's Proxy, formerly "Middleware") does a fast, cookie-only redirect for
|
||||
unauthenticated page/API requests — explicitly *not* the real security boundary. Every Route
|
||||
unauthenticated page/API requests — explicitly _not_ the real security boundary. Every Route
|
||||
Handler also calls `requireAuth()` itself; this is the actual auth check.
|
||||
- The WS `upgrade` handler is outside Next's request pipeline entirely, so it authenticates by hand
|
||||
(parsing the cookie header, or a `?token=` query param) via `authenticateUpgrade()`.
|
||||
|
||||
+55
-55
@@ -16,21 +16,21 @@ separate pre-flight step).
|
||||
|
||||
## `server`
|
||||
|
||||
| Field | Type | Default | Notes |
|
||||
|---|---|---|---|
|
||||
| `host` | string | `127.0.0.1` | Bind address |
|
||||
| `port` | number | `4173` | 1-65535 |
|
||||
| `basePath` | string | `""` | Reserved for future use |
|
||||
| Field | Type | Default | Notes |
|
||||
| ---------- | ------ | ----------- | ----------------------- |
|
||||
| `host` | string | `127.0.0.1` | Bind address |
|
||||
| `port` | number | `4173` | 1-65535 |
|
||||
| `basePath` | string | `""` | Reserved for future use |
|
||||
|
||||
## `auth`
|
||||
|
||||
| Field | Type | Default | Notes |
|
||||
|---|---|---|---|
|
||||
| `enabled` | boolean | `true` | `false` disables login entirely |
|
||||
| `sessionSecret` | string | — | Required, >= 32 chars, if `enabled`. Reference it via `${TRIGGERSHELL_SESSION_SECRET}` and set the real value in `.env`, not here |
|
||||
| `sessionTtlHours` | number | `12` | Session cookie lifetime |
|
||||
| `users` | array | `[]` | `{username, passwordHash}` — generate via `triggershell users add` |
|
||||
| `tokens` | array | `[]` | `{name, tokenHash}` — generate via `triggershell users add-token` |
|
||||
| Field | Type | Default | Notes |
|
||||
| ----------------- | ------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `enabled` | boolean | `true` | `false` disables login entirely |
|
||||
| `sessionSecret` | string | — | Required, >= 32 chars, if `enabled`. Reference it via `${TRIGGERSHELL_SESSION_SECRET}` and set the real value in `.env`, not here |
|
||||
| `sessionTtlHours` | number | `12` | Session cookie lifetime |
|
||||
| `users` | array | `[]` | `{username, passwordHash}` — generate via `triggershell users add` |
|
||||
| `tokens` | array | `[]` | `{name, tokenHash}` — generate via `triggershell users add-token` |
|
||||
|
||||
If `enabled: true`, at least one user or token must be configured.
|
||||
|
||||
@@ -42,67 +42,67 @@ pass `--inline` to those commands to get the raw hash printed for pasting into t
|
||||
|
||||
## `database`
|
||||
|
||||
| Field | Type | Default |
|
||||
|---|---|---|
|
||||
| Field | Type | Default |
|
||||
| ------ | ------ | ------------------------------- |
|
||||
| `path` | string | `.triggershell/triggershell.db` |
|
||||
|
||||
## `logs`
|
||||
|
||||
| Field | Type | Default | Notes |
|
||||
|---|---|---|---|
|
||||
| `dir` | string | `.triggershell/logs` | One `<runId>.log` file per run |
|
||||
| `retentionDays` | number | `30` | Not yet enforced automatically — prune manually or via cron |
|
||||
| Field | Type | Default | Notes |
|
||||
| --------------- | ------ | -------------------- | ----------------------------------------------------------- |
|
||||
| `dir` | string | `.triggershell/logs` | One `<runId>.log` file per run |
|
||||
| `retentionDays` | number | `30` | Not yet enforced automatically — prune manually or via cron |
|
||||
|
||||
## `scripts[]`
|
||||
|
||||
| Field | Type | Default | Notes |
|
||||
|---|---|---|---|
|
||||
| `id` | string | — | Required, unique, `[a-zA-Z0-9][a-zA-Z0-9_-]*` |
|
||||
| `name` | string | — | Required, display name |
|
||||
| `description` | string | — | Optional |
|
||||
| `command` | string | — | Required, e.g. `bash`, `node`, `./script.sh` |
|
||||
| `args` | string[] | `[]` | Fixed leading args, before variable-derived ones |
|
||||
| `cwd` | string | `./` | Resolved relative to the config file's directory |
|
||||
| `shell` | boolean | `false` | Opt-in shell interpretation — see the Security Notes in the README before using this |
|
||||
| `timeoutSeconds` | number | `1800` | 0–86400. `0` means no timeout - the run is never killed for taking too long |
|
||||
| `variables` | array | `[]` | See below |
|
||||
| Field | Type | Default | Notes |
|
||||
| ---------------- | -------- | ------- | ------------------------------------------------------------------------------------ |
|
||||
| `id` | string | — | Required, unique, `[a-zA-Z0-9][a-zA-Z0-9_-]*` |
|
||||
| `name` | string | — | Required, display name |
|
||||
| `description` | string | — | Optional |
|
||||
| `command` | string | — | Required, e.g. `bash`, `node`, `./script.sh` |
|
||||
| `args` | string[] | `[]` | Fixed leading args, before variable-derived ones |
|
||||
| `cwd` | string | `./` | Resolved relative to the config file's directory |
|
||||
| `shell` | boolean | `false` | Opt-in shell interpretation — see the Security Notes in the README before using this |
|
||||
| `timeoutSeconds` | number | `1800` | 0–86400. `0` means no timeout - the run is never killed for taking too long |
|
||||
| `variables` | array | `[]` | See below |
|
||||
|
||||
## `scripts[].variables[]`
|
||||
|
||||
Common fields on every variable:
|
||||
|
||||
| Field | Type | Default | Notes |
|
||||
|---|---|---|---|
|
||||
| `name` | string | — | Required, unique per script |
|
||||
| `label` | string | `name` | Display label |
|
||||
| `description` | string | — | Shown as form help text |
|
||||
| `required` | boolean | `false` | |
|
||||
| `secret` | boolean | `false` | Only valid on `type: string`. Masks the UI control, redacts from persisted run records |
|
||||
| `control` | string | type-based default | See mapping below |
|
||||
| `passAs` | `arg` \| `flag` \| `env` \| `stdin` | `arg` | How the value reaches the process |
|
||||
| `argName` | string | — | Required for `passAs: arg`/`flag`, e.g. `--env` |
|
||||
| `envName` | string | — | Required for `passAs: env`, e.g. `SLACK_CHANNEL` |
|
||||
| `joinWith` | string | `,` | Separator used when an array value is passed as a single arg/env string |
|
||||
| Field | Type | Default | Notes |
|
||||
| ------------- | ----------------------------------- | ------------------ | -------------------------------------------------------------------------------------- |
|
||||
| `name` | string | — | Required, unique per script |
|
||||
| `label` | string | `name` | Display label |
|
||||
| `description` | string | — | Shown as form help text |
|
||||
| `required` | boolean | `false` | |
|
||||
| `secret` | boolean | `false` | Only valid on `type: string`. Masks the UI control, redacts from persisted run records |
|
||||
| `control` | string | type-based default | See mapping below |
|
||||
| `passAs` | `arg` \| `flag` \| `env` \| `stdin` | `arg` | How the value reaches the process |
|
||||
| `argName` | string | — | Required for `passAs: arg`/`flag`, e.g. `--env` |
|
||||
| `envName` | string | — | Required for `passAs: env`, e.g. `SLACK_CHANNEL` |
|
||||
| `joinWith` | string | `,` | Separator used when an array value is passed as a single arg/env string |
|
||||
|
||||
Type-specific fields:
|
||||
|
||||
| `type` | Extra fields |
|
||||
|---|---|
|
||||
| `string` | `default?: string`, `pattern?: string` (regex), `minLength?`, `maxLength?`, `multiline?: boolean` |
|
||||
| `number` | `default?: number`, `min?`, `max?`, `step?` |
|
||||
| `boolean` | `default: boolean` (default `false`) |
|
||||
| `enum` | `choices: string[]` (required, non-empty), `default?: string` |
|
||||
| `multiselect` | `choices: string[]` (required, non-empty), `default: string[]` (default `[]`) |
|
||||
| `type` | Extra fields |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `string` | `default?: string`, `pattern?: string` (regex), `minLength?`, `maxLength?`, `multiline?: boolean` |
|
||||
| `number` | `default?: number`, `min?`, `max?`, `step?` |
|
||||
| `boolean` | `default: boolean` (default `false`) |
|
||||
| `enum` | `choices: string[]` (required, non-empty), `default?: string` |
|
||||
| `multiselect` | `choices: string[]` (required, non-empty), `default: string[]` (default `[]`) |
|
||||
|
||||
### UI control mapping
|
||||
|
||||
| `type` | Default `control` | Valid overrides |
|
||||
|---|---|---|
|
||||
| `string` | `text` (or `password` if `secret: true`) | `textarea` (needs `multiline: true`), `password` |
|
||||
| `number` | `number` | `slider` (requires both `min` and `max`) |
|
||||
| `boolean` | `checkbox` | `switch` |
|
||||
| `enum` | `select` | `radio` |
|
||||
| `multiselect` | `multiselect` (combobox) | `checkboxGroup` |
|
||||
| `type` | Default `control` | Valid overrides |
|
||||
| ------------- | ---------------------------------------- | ------------------------------------------------ |
|
||||
| `string` | `text` (or `password` if `secret: true`) | `textarea` (needs `multiline: true`), `password` |
|
||||
| `number` | `number` | `slider` (requires both `min` and `max`) |
|
||||
| `boolean` | `checkbox` | `switch` |
|
||||
| `enum` | `select` | `radio` |
|
||||
| `multiselect` | `multiselect` (combobox) | `checkboxGroup` |
|
||||
|
||||
### `passAs` semantics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user