From c344a0fd672a4734afc8c8f6170f8d05f17f1b08 Mon Sep 17 00:00:00 2001 From: Tim Trautmann Date: Fri, 29 May 2026 04:04:05 -0700 Subject: [PATCH] CLI: add `gs` as a short alias for ghoststandard Two bin entries pointing at the same dist/cli.js; Dockerfile symlinks both into /usr/local/bin/. `gs` is the daily-driver shorthand; `ghoststandard` stays as the longer form for any environment where `gs` collides (Ghostscript ships it on a lot of Linux distros, but not on our node:22-alpine base). Help text + README now lead with `gs `. --- .README.md.swp | Bin 0 -> 16384 bytes Dockerfile | 8 +++++--- README.md | 18 ++++++++++-------- package.json | 1 + src/cli.ts | 5 +++-- 5 files changed, 19 insertions(+), 13 deletions(-) create mode 100644 .README.md.swp diff --git a/.README.md.swp b/.README.md.swp new file mode 100644 index 0000000000000000000000000000000000000000..df23e36e8ea0777045114e0219e783cb26b12424 GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/Dockerfile b/Dockerfile index ee6654f..8d7457e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,9 +32,11 @@ RUN npm install --omit=dev && npm cache clean --force COPY --from=builder /app/dist ./dist -# Make `ghoststandard` available on $PATH so `docker compose exec app -# ghoststandard ` Just Works. -RUN chmod +x dist/cli.js && ln -s /app/dist/cli.js /usr/local/bin/ghoststandard +# Make both `gs` and `ghoststandard` available on $PATH so +# `docker compose exec app gs ` Just Works. +RUN chmod +x dist/cli.js \ + && ln -s /app/dist/cli.js /usr/local/bin/gs \ + && ln -s /app/dist/cli.js /usr/local/bin/ghoststandard VOLUME ["/data"] EXPOSE 8080 diff --git a/README.md b/README.md index 83ea86e..f628fbb 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ git clone cd ghoststandard mkdir -p assets && cp ~/path/to/icon.png assets/icon.png # 512×512 PNG, optional GS_HOSTNAME=bridge.example.com docker compose up -d -docker compose exec app ghoststandard setup +docker compose exec app gs setup ``` The wizard walks you through: @@ -36,14 +36,16 @@ The wizard walks you through: ## CLI -All admin runs through the CLI inside the container: +All admin runs through the CLI inside the container. `gs` is the short alias; the longer `ghoststandard` works identically if `gs` ever collides with something in your environment. ```bash -docker compose exec app ghoststandard setup # first-run wizard -docker compose exec app ghoststandard status # health + counts + last sync -docker compose exec app ghoststandard sync # manual sync one post -docker compose exec app ghoststandard unsync # manual delete one -docker compose exec app ghoststandard backfill # re-sync every published post +docker compose exec app gs setup # first-run wizard +docker compose exec app gs status # health + counts + last sync +docker compose exec app gs sync # manual sync one post +docker compose exec app gs unsync # manual delete one +docker compose exec app gs backfill # re-sync every published post +docker compose exec app gs set-icon # replace the icon +docker compose exec app gs set-theme # change the theme palette ``` The webhook receiver runs continuously as the container's main process; the CLI shares the same SQLite, so changes take effect immediately without restart. @@ -60,7 +62,7 @@ The webhook receiver runs continuously as the container's main process; the CLI │ │ (named volume) │ ▼ └──────────────────┘ ┌──────────┐ - │ CLI │ ← docker compose exec app ghoststandard … + │ CLI │ ← docker compose exec app gs … └──────────┘ ``` diff --git a/package.json b/package.json index 3166812..44acb59 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "license": "MIT", "type": "module", "bin": { + "gs": "./dist/cli.js", "ghoststandard": "./dist/cli.js" }, "scripts": { diff --git a/src/cli.ts b/src/cli.ts index c97f320..8d78ae5 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -26,7 +26,7 @@ function printHelp(): void { const cmd = pc.cyan; const arg = pc.dim; console.log(` -${pc.bold('ghoststandard')} ${pc.dim('— Ghost → Standard.site bridge')} +${pc.bold('gs')} ${pc.dim('— ghoststandard CLI — Ghost → Standard.site bridge')} ${pc.bold('Commands:')} ${cmd('setup')} First-run interactive setup @@ -40,7 +40,8 @@ ${pc.bold('Commands:')} ${arg(' light_orange, light_blue, dark_orange, skip)')} ${pc.dim('Run inside the container:')} - ${pc.dim('docker compose exec app ghoststandard ')} + ${pc.dim('docker compose exec app gs ')} + ${pc.dim('(or `ghoststandard ` — same binary, longer alias if `gs` collides)')} `); } -- 2.51.2