@hamedb89/localghost 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,361 +9,116 @@ Buh. Friendly local hostnames for app repos.
9
9
  [![CI](https://github.com/hamedb89/localghost/actions/workflows/ci.yml/badge.svg)](https://github.com/hamedb89/localghost/actions/workflows/ci.yml)
10
10
  [![GitHub Pages](https://github.com/hamedb89/localghost/actions/workflows/pages.yml/badge.svg)](https://github.com/hamedb89/localghost/actions/workflows/pages.yml)
11
11
  [![Publish npm](https://github.com/hamedb89/localghost/actions/workflows/publish-npm.yml/badge.svg)](https://github.com/hamedb89/localghost/actions/workflows/publish-npm.yml)
12
- [![npm version](https://img.shields.io/badge/npm-v0.1.8-CB3837?logo=npm)](https://www.npmjs.com/package/@hamedb89/localghost)
12
+ [![npm version](https://img.shields.io/badge/npm-v0.1.10-CB3837?logo=npm)](https://www.npmjs.com/package/@hamedb89/localghost)
13
13
 
14
- Localghost is a tiny Node.js CLI for friendly local domains in app repos. It gives each project one small contract for `.localhost` hostnames, Caddy reverse proxies, Vite `allowedHosts`, and the system hosts file, so developers can open `http://app.localhost/` instead of remembering which localhost port belongs to which process.
14
+ Localghost is a tiny Node.js CLI for clean local app domains. Add it as a dev dependency, keep running the command your team already knows, and use `http://app.localhost/` instead of remembering which port belongs to which process.
15
15
 
16
- [Website](https://hamedb89.github.io/localghost/) · [npm](https://www.npmjs.com/package/@hamedb89/localghost) · [GitHub](https://github.com/hamedb89/localghost)
16
+ [Website](https://hamedb89.github.io/localghost/) · [Docs](https://hamedb89.github.io/localghost/docs/) · [npm](https://www.npmjs.com/package/@hamedb89/localghost) · [GitHub](https://github.com/hamedb89/localghost)
17
17
 
18
- ## What It Does
19
-
20
- - Creates and reads `.localghost` in your app repo.
21
- - Lets repos choose explicit config files or filename patterns when `.localghost` is not enough.
22
- - Updates only a managed Localghost block in `/etc/hosts` during explicit setup.
23
- - Generates `ops/local/Caddyfile` for local reverse proxying. HTTP is the default; HTTPS is explicit with `--https` or `--ssl`.
24
- - Checks whether Caddy is installed, but does not run Homebrew for you.
25
- - Provides a Vite plugin that sets explicit `server.allowedHosts` entries.
26
- - Defaults Vite dev to the configured Localghost domain and no-ops during production/build.
27
- - Prints parsed config and project-local state as JSON for scripts, Codex, agents, and future MCP tools.
28
- - Checks npm for newer Localghost releases at most once per day, with an explicit opt-out.
29
-
30
- ## Trust
31
-
32
- - CI runs typecheck, build, site build, and npm package dry-run on Node 20 and 22.
33
- - GitHub Pages is deployed by Actions from the checked-in `site/` and `assets/` sources.
34
- - npm publish is guarded by `prepublishOnly` and the release workflow publishes with npm provenance.
35
- - Runtime dependencies are intentionally small: `commander` for the CLI and `execa` for process execution. Vite is an optional peer dependency for the Vite plugin.
36
- - No postinstall scripts, hidden Homebrew installs, or broad hosts-file rewrites.
37
- - Update checks are best-effort, cached for 24 hours, and can be disabled with `LOCALGHOST_NO_UPDATE_CHECK=1` or `--no-update-check`.
38
-
39
- <p align="center">
40
- <img src="./assets/localghost-app-icon.png" alt="Localghost app icon" width="180">
41
- </p>
42
-
43
- ## Install
18
+ ## Quick Start
44
19
 
45
20
  ```sh
46
21
  yarn add -D @hamedb89/localghost
47
22
  ```
48
23
 
49
- ## Quick Start
50
-
51
- Create the project config and optional package scripts:
52
-
53
- ```sh
54
- yarn localghost init --write-scripts
55
- ```
24
+ For Vite apps, add the plugin once:
56
25
 
57
- This creates `.localghost`:
26
+ ```ts
27
+ import { defineConfig } from "vite";
28
+ import { localGhostPlugin } from "@hamedb89/localghost/vite";
58
29
 
59
- ```txt
60
- # Buh. Friendly names for local services.
61
- # Format: <host> <port>
62
- app.localhost 5173
63
- www.app.localhost 5173
64
- api.app.localhost 8787
30
+ export default defineConfig({
31
+ plugins: [localGhostPlugin()]
32
+ });
65
33
  ```
66
34
 
67
- Check the machine:
35
+ Then keep using the command your repo already expects:
68
36
 
69
37
  ```sh
70
- yarn localghost doctor
38
+ yarn dev
71
39
  ```
72
40
 
73
- If Caddy is missing, Localghost prints:
41
+ On the first interactive run, Localghost can create `.localghost`, explain the `/etc/hosts` change, write `ops/local/Caddyfile`, and print the browser-facing URL:
74
42
 
75
43
  ```txt
76
- Caddy: missing
77
- Run: brew install caddy
78
- Localghost will not install it for you. No surprise spells.
79
- ```
80
-
81
- First time on a machine:
82
-
83
- ```sh
84
- yarn localghost:setup
85
- ```
86
-
87
- Check that the hosts block and Caddyfile are ready:
88
-
89
- ```sh
90
- yarn localghost:ready
91
- ```
92
-
93
- Daily proxy:
94
-
95
- ```sh
96
- yarn localghost:proxy
97
- ```
98
-
99
- Use HTTPS only when you explicitly want Caddy local certificates:
100
-
101
- ```sh
102
- yarn localghost:proxy:https
103
- ```
104
-
105
- Trust Caddy's local HTTPS CA when you want browsers to stop showing local certificate warnings:
106
-
107
- ```sh
108
- yarn localghost:trust
109
- ```
110
-
111
- Reset generated setup without deleting `.localghost`:
112
-
113
- ```sh
114
- yarn localghost:reset
115
- yarn localghost:setup
116
- ```
117
-
118
- Prefer `.localhost` names. `.local` is supported, but Localghost warns because `.local` can collide with mDNS/Bonjour.
119
-
120
- ## Config Files
121
-
122
- By default, Localghost reads `.localghost` from the project root. Repos that need another name can be explicit:
123
-
124
- ```sh
125
- localghost print --config .localghost.preview
126
- localghost setup --config .localghost.preview
127
- ```
128
-
129
- You can pass `--config` more than once. Localghost uses the first file that exists:
130
-
131
- ```sh
132
- localghost print --config .localghost.private --config .localghost
133
- ```
134
-
135
- You can also search project-root filenames with a regular expression:
136
-
137
- ```sh
138
- localghost print --config-pattern '^\.localghost\.(private|preview)$'
139
- ```
140
-
141
- The Vite plugin accepts the same shape through `fileName`, `configFiles`, or `configPattern`. If you run `localghost init --config .localghost.preview --write-scripts`, generated package scripts include the matching `--config` flag.
142
-
143
- ## Package Scripts
144
-
145
- `localghost init --write-scripts` adds these scripts when they are missing:
146
-
147
- ```json
148
- {
149
- "scripts": {
150
- "localghost:setup": "localghost setup",
151
- "localghost:proxy": "localghost dev",
152
- "localghost:proxy:https": "localghost dev --https",
153
- "localghost:run": "localghost run --",
154
- "localghost:ready": "localghost status --ready",
155
- "localghost:trust": "localghost trust",
156
- "localghost:ps": "localghost ps",
157
- "localghost:print": "localghost print",
158
- "localghost:routes": "localghost routes",
159
- "localghost:status": "localghost status",
160
- "localghost:reset": "localghost reset",
161
- "localghost:teardown": "localghost teardown",
162
- "localghost:doctor": "localghost doctor",
163
- "localghost:update": "localghost update",
164
- "caddy:setup": "localghost setup",
165
- "caddy:dev": "localghost dev"
166
- }
167
- }
168
- ```
169
-
170
- A full app might compose them with its own servers:
171
-
172
- ```json
173
- {
174
- "scripts": {
175
- "dev": "localghost run -- yarn dev:raw",
176
- "dev:dynamic": "localghost run --dynamic-port -- vite",
177
- "dev:raw": "vite"
178
- }
179
- }
180
- ```
181
-
182
- In Turborepo, let Localghost wrap the dev runner and keep dev uncached:
183
-
184
- ```json
185
- {
186
- "scripts": {
187
- "dev": "localghost run --dynamic-port -- yarn dev:raw",
188
- "dev:raw": "turbo dev"
189
- }
190
- }
191
- ```
192
-
193
- Then keep persistent dev tasks uncached:
194
-
195
- ```json
196
- {
197
- "tasks": {
198
- "dev": { "cache": false, "persistent": true }
199
- }
200
- }
201
- ```
202
-
203
- `localghost run` resolves one shared Localghost context, starts Caddy, handles the optional HTTPS trust prompt, then starts the child command. That keeps Localghost setup/proxy output before Vite's ready log. It passes the selected port to the child command through `LOCALGHOST_PORT` and `VITE_PORT`, and stops Caddy when the child exits. With `--dynamic-port`, Localghost starts at the configured port, checks `127.0.0.1:<port>`, and walks upward until it finds a free port.
204
-
205
- When settings need to be shared by the CLI wrapper and the Vite plugin, put them in `localghost.config.mjs`:
206
-
207
- ```js
208
- import { defineLocalghostConfig } from "@hamedb89/localghost";
209
-
210
- export default defineLocalghostConfig({
211
- project: "app",
212
- port: 5173,
213
- https: true,
214
- dynamicPort: true
215
- });
44
+ localghost
45
+ local: http://app.localhost/
46
+ also: http://www.app.localhost/
47
+ target: http://127.0.0.1:5173/
216
48
  ```
217
49
 
218
- Then the daily script can stay small:
50
+ For non-Vite apps, wrap your raw dev command:
219
51
 
220
52
  ```json
221
53
  {
222
54
  "scripts": {
223
55
  "dev": "localghost run -- yarn dev:raw",
224
- "dev:raw": "vite"
56
+ "dev:raw": "next dev"
225
57
  }
226
58
  }
227
59
  ```
228
60
 
229
- `www.` aliases are enabled by default. A `.localghost` entry like `app.localhost 5173` also sets up `www.app.localhost` unless `wwwAlias: false` is set in `localghost.config.mjs`.
230
-
231
- `localghost dev` and `localghost run` also register their active sessions in a user-local activity file. Use `localghost ps` to see the Localghost apps currently running on the machine:
232
-
233
- ```txt
234
- localghost ps
235
-
236
- app run: vite
237
- cwd: /Users/you/Projects/app
238
- pid: 12345, caddy: 12346, child: 12347
239
- started: 2026-07-05T12:00:00.000Z
240
- app.localhost -> 127.0.0.1:5173 (listening)
241
- ```
242
-
243
- Pass `--json` when another helper, such as a menu bar app, needs to poll the same state.
244
-
245
- ## macOS Widget
246
-
247
- Localghost includes a tiny native macOS menu-bar widget in `apps/macos-widget`. It shows `LG n` in the top bar, where `n` is the number of active Localghost-managed apps, and its menu lists each project, route, target port, and listening state.
248
-
249
- Build it from source:
250
-
251
- ```sh
252
- npm run build
253
- npm run macos:widget:build
254
- ```
255
-
256
- The app bundle is written to `dist/LocalghostWidget.app`. See [docs/macos-widget.md](./docs/macos-widget.md) for local development notes.
257
-
258
- ## Vite
259
-
260
- ```ts
261
- import { defineConfig } from "vite";
262
- import { localGhostPlugin } from "@hamedb89/localghost/vite";
263
-
264
- export default defineConfig({
265
- plugins: [
266
- localGhostPlugin({
267
- port: 5173,
268
- configFiles: [".localghost.private", ".localghost"]
269
- })
270
- ]
271
- });
272
- ```
273
-
274
- The plugin binds Vite to `127.0.0.1` by default, prints the selected Localghost domain, generates an explicit `server.allowedHosts` list from the selected config file, and does not set `allowedHosts: true`. It runs only during local `vite serve`; production/build mode no-ops. When `dynamicPort` is enabled in plugin options or `localghost.config.mjs`, the plugin uses the configured port when available and otherwise moves to the next free port before Vite starts.
275
-
276
- If `.localghost` is missing and Vite is running in an interactive terminal, the plugin asks whether to create one, prompts for the primary domain and optional extra domains, and then asks whether to run setup. Before touching `/etc/hosts`, it explains why macOS may ask for your password and confirms that only Localghost's managed block is changed.
277
-
278
- When Vite starts, Localghost prints the browser-facing URLs:
279
-
280
- ```txt
281
- localghost
282
- local: http://app.localhost/
283
- also: http://www.app.localhost/
284
- target: http://127.0.0.1:5173/
285
- ```
286
-
287
- `https: true` means the browser-facing URL is expected to go through Caddy on HTTPS, while Vite still runs behind it on `127.0.0.1:<port>`. The plugin uses that to set Vite websocket/HMR proxy settings and to print `https://...` local host URLs. Localghost never opens browser tabs by default.
61
+ ## What It Does
288
62
 
289
- Set `log: false` if you want to keep Vite's default terminal output only.
63
+ - Reads `.localghost` from your app repo and turns hostnames into local routes.
64
+ - Updates only a managed Localghost block in `/etc/hosts` during explicit setup.
65
+ - Generates `ops/local/Caddyfile` for local reverse proxying.
66
+ - Keeps HTTP as the default; HTTPS is explicit with `--https`, `--ssl`, or config.
67
+ - Checks whether Caddy is installed, but never installs Homebrew packages for you.
68
+ - Gives Vite explicit `server.allowedHosts` entries without using `allowedHosts: true`.
69
+ - Exposes CLI, config, state, and route output for scripts and agent workflows.
290
70
 
291
- ## CLI
71
+ ## Common Commands
292
72
 
293
73
  ```sh
294
- localghost init
295
74
  localghost init --write-scripts
296
75
  localghost doctor
297
76
  localghost setup
298
- localghost setup --project app
299
- localghost setup --config .localghost.preview
300
- localghost setup --https
301
- localghost trust
302
- localghost status
303
77
  localghost status --ready
78
+ localghost dev
79
+ localghost run -- vite
80
+ localghost routes
304
81
  localghost ps
305
- localghost ps --json
306
82
  localghost reset
307
83
  localghost teardown
308
- localghost teardown --remove-caddyfile
309
84
  localghost update
310
- localghost --no-update-check doctor
311
- localghost run -- vite
312
- localghost run --trust -- vite
313
- localghost run --dynamic-port -- turbo dev
314
- localghost dev --config-pattern '^\.localghost\.'
315
- localghost dev --https
316
- localghost print
317
85
  ```
318
86
 
319
- Localghost checks npm for newer releases after successful commands. The check has a short timeout, is cached for 24 hours, and never fails the command. Disable it with `LOCALGHOST_NO_UPDATE_CHECK=1` or `--no-update-check`. Run `localghost update` when you want an explicit update check.
320
-
321
- `setup`, `dev`, and `teardown` refuse to run in production-like environments such as `NODE_ENV=production`, `VERCEL_ENV=production`, or `LOCALGHOST_ENV=production`.
87
+ Prefer `.localhost` names. `.local` is supported, but Localghost warns because `.local` can collide with mDNS/Bonjour.
322
88
 
323
- When HTTPS is enabled, `localghost dev` and `localghost run` ask once whether to trust Caddy's local HTTPS CA. If you accept, macOS may ask for your password so Caddy can add its local CA to Keychain. Localghost records the result in `ops/local/localghost-state.json`; use `localghost trust` or `localghost run --trust -- ...` when you want to rerun the trust step intentionally.
89
+ ## Configuration
324
90
 
325
- `setup` writes only a managed block in the system hosts file:
91
+ Most apps only need a `.localghost` file when they want explicit hostnames or multiple services:
326
92
 
327
93
  ```txt
328
- # localghost:start app
329
- 127.0.0.1 app.localhost
330
- # localghost:end app
331
- ```
332
-
333
- Localghost does not rewrite the whole hosts file. It replaces only its own managed block for the selected project.
334
-
335
- ## Teardown And State
336
-
337
- `setup` writes a project-local state file at `ops/local/localghost-state.json`. It records the last Localghost action, selected config path, generated Caddyfile path, hosts file path, proxy mode, and the host entries that were applied. This is durable enough for project tooling and avoids relying on OS temp folders for tracking. Most apps should treat it as generated local state and ignore it in git.
338
-
339
- ```sh
340
- localghost status
341
- localghost status --ready
342
- localghost status --json
94
+ # Format: <host> <port>
95
+ app.localhost 5173
96
+ www.app.localhost 5173
97
+ api.app.localhost 8787
343
98
  ```
344
99
 
345
- `localghost dev` requires setup to be ready before it starts Caddy. If setup is missing or stale, it prints the exact `localghost setup` command instead of silently running `sudo`. Use `localghost dev --setup` only when you explicitly want the dev command to perform setup first.
346
-
347
- When a project no longer needs Localghost, teardown removes only the managed hosts block for the selected project:
100
+ Most repos do not need `localghost.config.mjs`. Add it only for decisions like HTTPS, dynamic-port behavior, `www.` aliases, custom config files, or `ghostTunnel` preview domains.
348
101
 
349
- ```sh
350
- localghost teardown
351
- ```
352
-
353
- When you want to retest setup without deleting `.localghost`, use reset:
102
+ ## Trust
354
103
 
355
- ```sh
356
- localghost reset
357
- localghost setup
358
- ```
104
+ - CI runs typecheck, build, site build, and npm package dry-run on Node 20 and 22.
105
+ - GitHub Pages is deployed by Actions from the checked-in `site/`, `docs/`, and `assets/` sources.
106
+ - Preview the exact Pages artifact locally with `npm run site:serve`, then open `http://127.0.0.1:4173/`.
107
+ - npm publish is guarded by `prepublishOnly` and the release workflow publishes with npm provenance.
108
+ - Runtime dependencies are intentionally small: `commander` and `execa`. Vite is an optional peer dependency.
109
+ - No postinstall scripts, hidden Homebrew installs, surprise browser tabs, or broad hosts-file rewrites.
110
+ - Update checks are best-effort, cached for 24 hours, and can be disabled with `LOCALGHOST_NO_UPDATE_CHECK=1` or `--no-update-check`.
359
111
 
360
- The generated Caddyfile is left in place by default. Remove it explicitly when you want a fuller cleanup:
112
+ ## Docs
361
113
 
362
- ```sh
363
- localghost teardown --remove-caddyfile
364
- ```
114
+ The full docs are served on GitHub Pages:
365
115
 
366
- Localghost still uses a short-lived OS temp file while copying `/etc/hosts` with `sudo`, but that temp file is not the source of truth.
116
+ - [User flows](https://hamedb89.github.io/localghost/docs/flows/)
117
+ - [CLI reference](https://hamedb89.github.io/localghost/docs/localghost.1/)
118
+ - [Ghost Tunnel guide](https://hamedb89.github.io/localghost/docs/ghost-tunnel/)
119
+ - [macOS widget notes](https://hamedb89.github.io/localghost/docs/macos-widget/)
120
+ - [Brand guidelines](https://hamedb89.github.io/localghost/docs/brand/)
121
+ - [All docs](https://hamedb89.github.io/localghost/docs/)
367
122
 
368
123
  ## API
369
124
 
@@ -380,35 +135,9 @@ import {
380
135
  updateSystemHosts
381
136
  } from "@hamedb89/localghost";
382
137
 
383
- readDevHosts({ configFiles: [".localghost.private", ".localghost"] });
384
- readDevHosts({ configPattern: /^\.localghost\.(private|preview)$/ });
385
- ```
386
-
387
- Vite helper:
388
-
389
- ```ts
390
138
  import { localGhostPlugin } from "@hamedb89/localghost/vite";
391
139
  ```
392
140
 
393
- `localHostsPlugin` is also exported as a compatibility alias.
394
-
395
- ## More Docs
396
-
397
- Localghost copy can be mysterious, goofy, magical, funny, and a little absurd. The product behavior should stay boring in the best way: explicit commands, exact paths, clear errors, and no hidden installs.
398
-
399
- - [Website](https://hamedb89.github.io/localghost/)
400
- - [Brand guidelines](./docs/brand.md)
401
- - [Job-to-be-done flows](./docs/flows.md)
402
- - [CLI reference](./docs/localghost.1.md)
403
-
404
- ## Assets
405
-
406
- <p align="center">
407
- <img src="./assets/localghost-mascot.png" alt="Localghost mascot" width="180">
408
- <br>
409
- <img src="./assets/localghost-wordmark.png" alt="Localghost wordmark" width="420">
410
- </p>
411
-
412
141
  ## License
413
142
 
414
143
  MIT
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>com.apple.security.app-sandbox</key>
6
+ <true/>
7
+ <key>com.apple.security.application-groups</key>
8
+ <array>
9
+ <string>group.app.localghost</string>
10
+ </array>
11
+ </dict>
12
+ </plist>