CLI reference
The pageship command signs you in, publishes HTML files as documents, and manages the documents you published. It also installs the Pageship skills for your agents. Commands use the hosted Pageship service unless you pass --server.
Each command prints a short message for a person. Add --json to get one JSON result instead. Agents use JSON.
Install
Section titled “Install”The CLI needs Node.js 24.11 or newer. Install it globally with your package manager:
npm i -g pageship
pnpm add -g pageship
bun add -g pageship
Check that your shell finds it:
pageship --version
To update it later, run pageship update.
To run a command without installing the CLI, put npx in front of it, as in npx pageship status.
To have an agent install the CLI and the skills and sign you in, give it the setup guide instead.
Commands
Section titled “Commands”| Command | What it does |
|---|---|
login |
Authorize this installation in a browser and choose your address. |
whoami |
Show who is signed in and this installation’s ID. |
status |
Check whether this installation is ready to publish. Changes nothing. |
skills install |
Install the Pageship skills for your agents. |
publish |
Publish an HTML file as a new document or a new revision. |
list |
List your documents. |
history |
List a document’s revisions. |
download |
Save a document’s HTML to a new file. |
visibility |
Make a document private or public. |
viewers |
List, add or remove the GitHub users who can read a private document. |
restore |
Make an earlier revision current again. |
update |
Update the CLI with the package manager that installed it. |
Run pageship on its own, or any command with --help, to see its usage and options.
Sign in
Section titled “Sign in”Authorizes this installation through your browser, then sets your workspace address.
pageship login
Open <link>
Check code <code>. Only approve an installation you started.
Waiting for approval. Press Ctrl+C to stop; you can resume with pageship login --complete.
Authorized as Ada Lovelace. Your credential is stored privately for this server. Workspace address: ada.pageship.dev.
In a terminal, login shows a link and a code, then waits. Open the link on any machine and approve the code with your invited GitHub account. Press Ctrl+C to stop waiting; pageship login --complete resumes later.
Without a terminal, or with --json, login returns at once with authorization_pending, the link in verificationUriComplete, the code in userCode, and next set to login --complete. Approve the code, then run that command.
After you approve, login keeps your existing workspace address, or claims your GitHub login as the address. If that name is reserved or taken, you choose from generated addresses. You cannot type an address of your own.
- In a terminal, type a number to pick one,
rfor new choices, orqto cancel. - Without a terminal, login returns
choice_requiredwith the choices.resolutionsholds one completelogin --address-choicecommand for each, pluslogin --refresh-addresses.
Cancelling or interrupting the choice keeps your credential.
When this installation is already signed in, login reuses the stored credential and only sets the address. Use --restart to sign in again, for example with another account.
| Option | What it does |
|---|---|
--complete |
Check a waiting authorization once, without waiting. |
--restart |
Drop any waiting authorization and start with a new code, even when signed in. |
--address-choice <choiceId> |
Select one of the generated addresses that login offered. |
--refresh-addresses |
Replace the offered addresses with new ones. Not together with --address-choice. |
--server <origin> |
Use another server. |
Login returns:
authorized, exit 0: signed in, with the selectedaddress. Only this result means the workspace is ready to publish.authorization_pending, exit 2: approve the code in the browser, then runnext.expired, exit 2: the code expired.nextstarts a new one.choice_required, exit 2: pick an address fromresolutions.select, or new choices withresolutions.refresh.reauthentication_required, exit 2: sign in to the dashboard again so Pageship can check your GitHub login, then runnext.signed_out, exit 2: the server rejected the new credential.nextislogin --restart.cancelled, exit 2: you typedqat the address prompt.nextoffers the choice again.denied, exit 1: the code was denied in the browser.invalid_attempt, exit 1:--completefound no waiting authorization, or the server refused the code for another reason.uninvited, exit 1: the GitHub account is not invited to this server.invalid_action, exit 1:--address-choiceand--refresh-addresseswere used together.interrupted, exit 130: Ctrl+C.nextresumes.
whoami
Section titled “whoami”Shows who is signed in, using the stored credential.
pageship whoami
Signed in as Ada Lovelace. Personal workspace: <workspaceId>
CLI installation: <installationId>
The JSON result is admitted, exit 0, with user (id, name), workspace (id), installation (id) for a CLI credential, and the selected address. Without a credential, or when the server rejects it, the result is signed_out, exit 2, with next set to login. An account that is not invited returns uninvited, exit 1.
| Option | What it does |
|---|---|
--server <origin> |
Use another server. |
Revoke an installation
Section titled “Revoke an installation”Each installation has its own credential. The installation ID that whoami prints is not secret. To revoke one, find that ID in the dashboard’s list of CLI installations and select Revoke access. Its next request returns signed_out, exit 2. Other installations stay signed in. Run login on it to authorize it again.
Check readiness
Section titled “Check readiness”status
Section titled “status”Reports whether this installation is ready to publish, and whether the Pageship skills are installed and current.
pageship status
Compatible with API major 1. Server 0.1.0; supported API majors: 1.
Signed in as Ada Lovelace.
Personal workspace: <workspaceId>
CLI installation: <installationId>
Workspace address: ada.pageship.dev
Publishing setup is complete. Status does not check storage or publish anything.
The Pageship skills match this CLI (0.1.1).
Status checks the service’s API version, then reads the stored credential and your personal workspace. It only reads. It never starts a sign-in, opens a browser, claims an address, uploads anything, or creates or changes a file in the configuration directory. A ready result does not prove that storage works or that a publish will succeed. Each request times out after 10 seconds. It also asks the npm registry for the latest CLI version, for up to 5 seconds.
| Option | What it does |
|---|---|
--server <origin> |
Use another server. |
Status returns:
admitted, exit 0: signed in with a selected address, ready to publish. A server too old to report the address leaves it out;nextis then an optionalloginthat confirms or chooses one.address_required, exit 2: signed in, but no address is selected.addressisnull, andnextis theloginthat selects one.signed_out, exit 2: no stored credential, or the server rejected it.nextislogin, with--completewhen an authorization is waiting for approval, or--restartwhen it expired.uninvited, exit 1: the GitHub account is not invited to this server.unreachable, exit 1: the service did not answer.client_too_old,server_too_oldorunsupported, exit 1: the CLI and the server share no API version. The message says which one to update.configuration_unreadable, exit 1: the configuration directory exists but its credentials cannot be read. The message names the directory and how to fix it.
admitted and address_required include user, workspace, installation and address as for whoami. Every result except unreachable also has requiredApiMajor and server, with the server’s serverVersion, currentApiMajor and supportedApiMajors.
Every status result also reports the skills, and these never change the status or the exit code:
skills:missing,current, orolderthan this CLI. When the skills are not current and nothing else needs doing,nextisskills install.cliandlatest: whether this CLI iscurrentorolderthan the version npm publishes as latest, and that version. Both are left out when the registry doesn’t answer. An older CLI gets noskills installinnext, since it would install its own older skills. Runupdate, then install the skills.missing: what else the CLI looked for and did not find. It can name the recommended skillsfrontend-designanddesign-taste-frontend, andnode. The authoring skills’ scripts run with Node 20 or newer from yourPATH, which can differ from the Node that runs the CLI.
Install the skills
Section titled “Install the skills”skills install
Section titled “skills install”Installs the Pageship skills that ship inside the CLI: the pageship platform skill, which publishes with this CLI, and the pageship-docs authoring skills, which write documents. See Pageship skills for what each one does.
pageship skills install
Installed 17 Pageship skills for CLI 0.1.1 in /home/ada/.agents/skills.
Linked them from /home/ada/.claude/skills for Claude Code.
It copies each skill to ~/.agents/skills/<name>, which Codex, Cursor, Copilot, Gemini CLI, OpenCode, Amp, Pi, Goose and Windsurf read. When ~/.claude exists, it also links ~/.claude/skills/<name> to that copy for Claude Code. On Windows it copies instead of linking. It installs for your user, not for one project.
The CLI owns the pageship and pageship-* folders there. It records each folder it writes, with its version and a hash of its content, in skills.json in the configuration directory. Running the install again, for example after you update the CLI, replaces those folders and removes the ones this version no longer ships. It leaves other pageship-* folders alone.
| Option | What it does |
|---|---|
--force |
Replace Pageship skill folders that were changed since, or that this CLI did not install. |
It returns:
skills_installed, exit 0: lists every folder and link it wrote infoldersandlinks, and the folders it removed inremoved.skills_modified, exit 1: a folder it would replace or remove was changed since, or it has no record of writing it. It names them infoldersand writes nothing.resolutions.forceholdsskills install --force.
Both results list in missing what else the CLI looked for, as status does: the recommended skills, in ~/.agents/skills, ~/.claude/skills and Claude Code plugins, and Node 20 or newer. The CLI never installs them, and they never change the result. The setup guide covers them.
To remove the skills, delete the pageship and pageship-* folders in ~/.agents/skills and ~/.claude/skills.
Update the CLI
Section titled “Update the CLI”update
Section titled “update”Updates this CLI to the version npm publishes as latest, with the package manager that installed it.
pageship update
Running npm i -g pageship@0.6.0
changed 1 package in 2s
Updated Pageship from 0.5.0 to 0.6.0 with npm i -g pageship@0.6.0.
Run pageship skills install to update the Pageship skills to match.
It tells the package manager from the folder the CLI is installed in, and runs that manager’s global install:
| Installed with | Runs |
|---|---|
| npm | npm i -g pageship@<version> |
| pnpm | pnpm add -g pageship@<version> |
| bun | bun add -g pageship@<version> |
| Yarn 1 | yarn global add pageship@<version> |
| Vite+ | vp install -g pageship@<version> |
It installs the exact version npm publishes as latest. When the registry doesn’t answer, it installs pageship@latest and lets the package manager choose. In a terminal you see the package manager’s output as it runs. With --json, the CLI collects that output and returns it in output only when the update fails.
It returns:
cli_updated, exit 0: the package manager installed the new version.managernames it,runis the command it ran,versionis the version you had andlatestthe one installed. When the Pageship skills are installed,nextisskills install, since they still match the old version.cli_current, exit 0: this CLI is already the latest version. Nothing ran.install_unknown, exit 1: no supported package manager installed this CLI globally, for example when it is a project dependency or runs throughnpx.pathis the folder it runs from. Nothing ran; update it the way you installed it.update_failed, exit 1: the package manager failed or could not start.exitCodeandoutputhold what it returned, and the message says what went wrong, such as missing permission to write its global folder.
Publish documents
Section titled “Publish documents”publish
Section titled “publish”Publishes one HTML file. The first publish creates a private document; later publishes of the same file add revisions to it.
pageship publish report.html
Published privately as a new document: https://ada.pageship.dev/d/Ab12Cd-report
The file must end in .html or .htm, and its path can be relative or absolute. A file over the size limit, 10,000,000 bytes unless the server sets another, is refused before upload. Publishing needs a selected workspace address; without one, publish returns address_required with next set to login.
| Option | What it does |
|---|---|
--new |
Create a separate private document, even when the file matches an existing one. |
--revise <documentId> |
Publish a new revision of this document. Needs --expected-revision. |
--expected-revision <revisionId> |
The document’s current revision, as you last saw it. A newer revision stops the publish. |
--no-marker |
Publish the file as it is, without adding or changing its document marker. |
--idempotency-key <key> |
Retry an unfinished publish with the key its result returned. |
--server <origin> |
Use another server. |
Use --new alone, or --revise together with --expected-revision. The old --address-choice and --refresh-addresses options no longer work on publish; they return invalid_action with the matching login command in next.
How publish finds the document
Section titled “How publish finds the document”A plain publish, without --new or --revise, looks for the file’s document in this order:
- The file’s document marker.
- The publish manifest, for a file this machine published before.
- The file’s repository and path, for a file in a Git checkout.
When none of them matches, it creates a new document. The message says which it did, “as a new document” or “as a new revision”, and the JSON result has change set to created or revised.
A file in a Git checkout with an origin remote belongs to a repository, recorded as its normalized remote without credentials, such as github.com/UzEE/tracksmith. Any other file is a loose file, and a loose file is never matched by its path. The source path is relative to the file’s Git checkout, or else to the current directory, or else, for a file outside the current directory, to the file’s own folder. The repository is fixed when the document is created; the path updates on every publish from a file in a repository. Each revision records the CLI version that published it.
Document markers
Section titled “Document markers”A published file ends with a document marker, an HTML comment that names its document and does not render:
<!-- pageship:v1 document=Ab12Cd -->
For a new document, the CLI proposes the ID, uploads the file with the marker added, and writes the same marker to the local file only after the upload succeeds. The local file and the published revision then hold the same bytes. If the proposed ID is taken, the CLI retries with a fresh one. An existing marker is replaced, never duplicated, and no other byte changes. The CLI skips the write if the file changed during the upload. If it cannot write the file, for example because it is read-only, the publish still succeeds and the message warns that the file has no marker. A UTF-16 file is published without a marker, with a warning.
A marked file revises its document without asking when the manifest links this path to it, or when the file belongs to the document’s repository, for example in another checkout of it. A marked loose file matches a loose document. Otherwise:
- When the repositories differ, for example in a fork, the result is
repository_mismatch, exit 2, with thedocumentandresolutions. Nothing changes. - When the marker names a document that does not exist or is not yours, the result is
marker_unavailable, exit 2, before any upload.nextis the same publish with--new.
--new points the marker at the new document, and --revise at the named one. --no-marker leaves the file untouched, and the follow-up commands it returns keep --no-marker.
Publish manifest
Section titled “Publish manifest”After each successful publish, the CLI records the file’s real path, document ID and revision ID in a publish manifest for that server, next to the credentials. A symbolic link resolves to its real path first.
Publishing the same real path again revises that document without asking, and expects the recorded revision. If the document changed since, for example from another machine or the dashboard, the result is revision_conflict, exit 2, with the current document and resolutions. Nothing changes. A retry with an older --idempotency-key leaves a newer entry, and the file’s marker, as they are. For a file without a marker, an entry whose document was deleted or is not yours is ignored, and the next successful publish replaces it. --new and --revise skip the manifest and point the entry at the published document.
Matching documents
Section titled “Matching documents”When a file in a repository without a marker or manifest entry has the same repository and path as published documents, publish changes nothing and asks which one you meant. In a terminal:
This source path matches published documents:
1. reports/report.html (Ab12Cd) https://ada.pageship.dev/d/Ab12Cd-report
o <number> to open, r <number> to revise, n for a separate document, or q to cancel:
o 1 opens the document in your browser and asks again. r 1 publishes a revision of it, n creates a separate document, and q cancels with cancelled, exit 2. Opening and cancelling change nothing.
Without a terminal, or with --json, the result is source_collision, exit 2, with the matching candidates and resolutions: new, and one revise entry for each candidate. Each entry is a complete command to run.
To revise a document from any file, for example a moved file or a loose file on another machine, name it:
pageship publish report.html --revise Ab12Cd --expected-revision <revisionId>
Retries
Section titled “Retries”If a publish fails in transit or you interrupt it, next repeats it safely. Once the upload has started, next carries --idempotency-key with the result’s idempotencyKey; run it with the file unchanged. A key reused with the same input returns the same publication; with different input it returns idempotency_conflict.
Results
Section titled “Results”published, exit 0:documentholds itsid,slug,title,sourcePath,repository,visibility, currentrevisionId,byteLength,createdAtandurl, andchangeiscreatedorrevised.address_required,source_collision,repository_mismatch,marker_unavailable,revision_conflict,cancelledorsigned_out, exit 2: nothing changed. Runnext, or the entry inresolutionsyou choose.invalid_file,upload_too_large,invalid_action,idempotency_conflict,unavailableordocument_id_taken, exit 1: fix the cause, then publish again.unavailablemeans the document named by--reviseis not found or not yours.publication_action_unsupported, exit 1: the server is too old for--newor--revise. Nothing was uploaded.request_failed, exit 1, orinterrupted, exit 130:nextretries safely.
Manage documents
Section titled “Manage documents”These commands use the stored credential and work only on your own documents. A document that does not exist or is not yours returns unavailable, exit 1. Each result carries the IDs the next command needs.
Lists your documents, 100 at a time.
pageship list
Documents:
Ab12Cd private 2 viewers report
repository github.com/ada/reports
source reports/report.html
current revision 5f3c2a1e-8b7d-4c6e-9f0a-1b2c3d4e5f6a
https://ada.pageship.dev/d/Ab12Cd-report
The JSON result is listed, exit 0, with documents. Each document has its ID, title, repository, source path, visibility, number of viewers (sharedWith), current revision and URL. When more exist, the output ends with the command for the next page, and the JSON result has nextCursor and next.
| Option | What it does |
|---|---|
--cursor <documentId> |
Continue after the nextCursor of the previous page. |
--server <origin> |
Use another server. |
history
Section titled “history”Lists a document’s revisions, newest first, 50 at a time, and marks the current one.
pageship history Ab12Cd
Revisions of Ab12Cd, newest first:
5f3c2a1e-8b7d-4c6e-9f0a-1b2c3d4e5f6a current 2026-10-19T09:30:00.000Z 18204 bytes
https://ada.pageship.dev/d/Ab12Cd-report/revisions/5f3c2a1e-8b7d-4c6e-9f0a-1b2c3d4e5f6a
The JSON result is listed, exit 0, with revisions. In JSON, each revision names the cliVersion that published it, or null for a restoration. Paging works as for list. History is visible only to you, even for a public document.
| Option | What it does |
|---|---|
--cursor <revisionId> |
Continue after the nextCursor of the previous page. |
--server <origin> |
Use another server. |
download
Section titled “download”Saves the exact stored HTML of a document’s current revision, or of an earlier one, to a new file.
pageship download Ab12Cd --output report.html
pageship download Ab12Cd --revision <revisionId> --output old.html
Saved 18204 bytes of Ab12Cd to /home/ada/reports/report.html.
Download never replaces a file. When the --output file exists, the result is output_exists, exit 1, and the file is unchanged. A path it cannot write returns invalid_output, exit 1. The JSON result downloaded has the absolute output path, byteLength, and revisionId, which is null for the current revision.
| Option | What it does |
|---|---|
--output <file> |
Required. The new file to write. |
--revision <revisionId> |
Download this earlier revision instead of the current one. |
--server <origin> |
Use another server. |
visibility
Section titled “visibility”Makes a document private or public.
pageship visibility Ab12Cd public
pageship visibility Ab12Cd private
Ab12Cd is public. Anyone with the URL can read its current revision: https://ada.pageship.dev/d/Ab12Cd-report
Anyone with the URL can read a public document’s current revision without signing in. A private document is readable only by you and its viewers, after signing in. Making a document public removes all its viewers, and the output says how many; making it private again does not bring them back. Visibility changes nothing else. The JSON result is visibility_updated, exit 0, with the saved document and removedViewers, the number of viewers removed.
| Option | What it does |
|---|---|
--server <origin> |
Use another server. |
viewers
Section titled “viewers”Lists the GitHub users who can read a private document, or adds and removes them. A viewer signs in with GitHub to read the document’s current revision. Pageship sends no invitations: send them the URL yourself.
pageship viewers Ab12Cd
pageship viewers Ab12Cd --add octocat --add hubot
pageship viewers Ab12Cd --remove octocat
Found octocat (The Octocat), GitHub ID 583231.
Added octocat (The Octocat), GitHub ID 583231.
Viewers of Ab12Cd:
octocat (The Octocat), GitHub ID 583231
--add looks the username up on GitHub, prints the account it found and adds that account. Only a personal account can be a viewer. A public document can’t have viewers: make it private first. --remove takes a viewer’s username or GitHub ID and matches it against the document’s viewers. A value of only digits is always a GitHub ID, so remove a viewer whose username is all digits by their GitHub ID. A viewer’s username is the one they had when added or last signed in, so after a GitHub rename two viewers can share one. If a username matches more than one viewer, the result is ambiguous_viewer, exit 1, with the viewers in matches; nothing changes, and you remove one by its GitHub ID.
The command matches every --remove and looks up every --add before it changes anything, then applies the removals and additions together: all of them or none. It takes up to 20 --add and 50 --remove values. Without --add or --remove, the JSON result is listed, exit 0, with viewers. Otherwise it is viewers_updated, exit 0, with added, removed, notViewers for --remove values that matched no viewer, and viewers. If the change fails, nothing changed, and its next repeats the command.
GitHub lookups use the GitHub sign-in Pageship holds for you, not the CLI credential. If GitHub refuses it, the result is github_sign_in_required, exit 2: sign in to the dashboard again with GitHub, then run next.
| Option | What it does |
|---|---|
--add <username> |
Look up this GitHub username and add the account as a viewer. Repeatable. |
--remove <username or ID> |
Remove the viewer with this GitHub username or GitHub ID. Repeatable. |
--server <origin> |
Use another server. |
restore
Section titled “restore”Copies an earlier revision’s content into a new current revision.
pageship restore Ab12Cd --revision <revisionId> --expected-revision <currentRevisionId>
Restored revision <revisionId> as new current revision <newRevisionId>. Earlier revisions remain in history, and Ab12Cd stays private: https://ada.pageship.dev/d/Ab12Cd-report
Pass the current revision you saw in history as --expected-revision. If the document changed since, the result is revision_conflict, exit 2, with the current document, and next is the history command; nothing is restored. The JSON result is restored, exit 0, with the document and its new current revision. Restoring the current revision returns invalid_restore, exit 1. Visibility, the URL and earlier revisions stay the same.
If a restore fails in transit or you interrupt it, it may still have finished. Run the returned next, which carries --idempotency-key, to get the original result without restoring twice. Reusing that key with other arguments returns idempotency_conflict, exit 1.
| Option | What it does |
|---|---|
--revision <revisionId> |
Required. The earlier revision to restore. |
--expected-revision <revisionId> |
Required. The current revision you saw. A newer one stops the restore. |
--idempotency-key <key> |
Retry an unfinished restore with the key its result returned. |
--server <origin> |
Use another server. |
Options for every command
Section titled “Options for every command”These work with every command. --json can go before or after the command name.
JSON output
Section titled “JSON output”--json prints one JSON object on one line to standard output, and nothing else: no prompts, no progress and no browser. Help, version and usage errors are JSON too. See JSON results.
pageship --json status
pageship status --json
After the -- separator, --json is an ordinary argument.
Help and version
Section titled “Help and version”--help, or -h, prints usage and options, for the CLI or for one command. --version, or -v, prints the CLI’s version, such as pageship v0.1.1. Both exit 0.
Wizard, completions and log level
Section titled “Wizard, completions and log level”--wizard, --completions and --log-level come from the CLI’s command-line library and work only without --json.
--wizardbuilds a command by asking for each part in turn.--completions <shell>prints a shell completion script forbash,zsh,fishorsh.--log-level <level>sets the minimum level of log messages. Pageship writes none of its own.
JSON results
Section titled “JSON results”Every JSON result has these fields:
| Field | Meaning |
|---|---|
ok |
true only when outcome is succeeded: the command finished, with nothing left for you to do. |
command |
The command, such as status, skills, help or version. null when none was recognized, or on internal_error. |
outcome |
succeeded, pending or failed. |
status |
The specific result, as listed under each command. |
message |
The text a person would see. Show it; don’t parse it. |
next |
One follow-up command, when there is one. |
resolutions |
Named follow-up commands to choose from, when a decision is waiting. |
Other fields depend on the status, such as document, candidates or user. No result contains a credential.
next and each entry in resolutions have a command and an args list. Run one as pageship --json <command> <args...>, with the arguments unchanged. They already carry what the follow-up needs, such as the document ID, the expected revision and the idempotency key, and never contain placeholders.
A successful publish, for example, prints this, shown here across several lines:
{
"ok": true,
"command": "publish",
"outcome": "succeeded",
"status": "published",
"message": "Published privately as a new document: https://ada.pageship.dev/d/Ab12Cd-report",
"change": "created",
"document": {
"id": "Ab12Cd",
"slug": "report",
"title": "report",
"sourcePath": "reports/report.html",
"repository": "github.com/ada/reports",
"visibility": "private",
"revisionId": "5f3c2a1e-8b7d-4c6e-9f0a-1b2c3d4e5f6a",
"byteLength": 18204,
"createdAt": 1792402200000,
"url": "https://ada.pageship.dev/d/Ab12Cd-report"
},
"idempotencyKey": "0192f3c5-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
}
Exit codes
Section titled “Exit codes”The exit code follows the outcome, in human and JSON modes.
| Exit code | Outcome |
|---|---|
0 |
succeeded |
1 |
failed: fix the cause first. |
2 |
pending: waiting for your approval or choice. Run next or a resolution. |
130 |
failed with interrupted: Ctrl+C or SIGTERM. |
Any command can also fail with usage_error for invalid arguments, request_failed for a network, server or storage failure, or internal_error for a defect in the CLI, each exit 1. A command that contacts the server returns client_too_old, server_too_old or unsupported, exit 1, when the CLI and the server share no API version. A command that needs sign-in returns signed_out, exit 2, with next set to login, or uninvited, exit 1, when the account is not invited to the server.
Use another server
Section titled “Use another server”Add --server <origin> to any command except skills install and update to use another Pageship server instead of the hosted API at https://api.pageship.dev. It applies to that command only. Use it for development, testing or another deployment. No environment variable or file selects a server.
pageship status --server http://localhost:8787
pageship login --server http://localhost:8787
The value is an HTTPS origin with no path, credentials, query or fragment. HTTP is allowed only on localhost, 127.0.0.1 and [::1]. Credentials and waiting authorizations are kept separately for each server, so signing in to one does not sign you in to another. When you pass --server, every follow-up command the CLI returns for that server includes it. A skills install follow-up has no --server.
Configuration directory
Section titled “Configuration directory”The CLI keeps its credentials, the publish manifest and the skills record in one private directory:
$PAGESHIP_CONFIG_DIR, when set. It must be an absolute path to a private directory.- Otherwise
$XDG_CONFIG_HOME/pageship, or~/.config/pageship, on macOS and Linux. - Otherwise
%LOCALAPPDATA%\pageshipon Windows.
Credentials are plain JSON, stored per server origin and never printed. On macOS and Linux the directory is owner-only and the files have mode 0600. On Windows they inherit your user profile’s permissions; the CLI sets no access control lists.