crewship page designedits a Design artifact (a canvas of frames, shapes, text and images) and manages its versions, shared version and comments.crewship craftopens a human edit session on a native Craft document (Word), takes the lease, reads and saves whole-document versions and starts agent tasks.crewship mooring connectexchanges the original protocol frames of a Mooring collaboration session over a WebSocket.
page root for historical reasons; the objects
they create are Artifacts and appear in the Artifacts library when the web
library is enabled. Per-flag details for every subcommand stay in
crewship page, crewship craft and
crewship mooring.
All examples use a human CLI login (crewship login) and the workspace selected
with --workspace or CREWSHIP_WORKSPACE. Outputs were recorded against a test
workspace and shortened; IDs are replaced with placeholders.
Before you start
Everything on this page is off by default.
Check the current workspace flags with
crewship feature-flag list. Instance
switches are described in Environment variables.
Output and exit codes
page design commands always print the server’s JSON object; the default
format, -f json and -f table give the same JSON, and -f yaml prints YAML.
craft commands print one JSON line per response (NDJSON) or YAML documents
separated by --- with -f yaml; craft availability prints a single object.
page design watch and mooring connect refuse -f quiet; craft has no
quiet mode and prints NDJSON under -f quiet, including the watch stream.
Errors go to stderr. With the default format they are one line of text; with
-f json, -f ndjson or -f yaml they use the standard CLI error envelope.
For page design the envelope carries the HTTP status and server text, and the
exit code follows the status:
Craft HTTP refusals use the standard classified codes:
400/422 → 2,
401/403 → 4, 404 → 3, 409 → 5, 429 → 6, and 5xx → 7.
A connection failure before a response uses 8. Human native operations
include the HTTP status and server error body in the envelope, with the private
session token removed. Lease and proposal refusals can add context; see
Craft errors.
Native agent task commands keep status-only messages because their refusal
bodies can describe a private runtime. Their envelope carries only message
and the classified exit_code, for example:
craft version <page> <version> requires a canonical positive decimal integer
within the signed 64-bit range. Invalid versions (such as 0, 01, +1, a
negative value or an overflowing number) exit with validation code 2 before
authentication or any HTTP request; the error envelope also carries
exit_code: 2.
Pass a negative positional value after --, for example
crewship craft version @<artifact-id> -- -1, so it is checked as a version
instead of parsed as a flag.
The local page design create check for a missing --name and the
page design restore/share checks for an invalid --version still return
unclassified code 1 before any request. These specific checks do not define
the exit code for other commands’ argument validation.
Design artifacts
Permissions
Create a Design and add content
409 Design changed; reload and reapply.
Edits are a JSON object with operations (1 to 500) and an optional message.
An upsert carries a whole node: id, type (frame, rect, text or
image), name, x, y, width, height, fill and optionally
parentId, text, src or linkTo. linkTo is the ID of the screen that a
click on the layer opens in prototype playback; "" removes it. A text layer
also takes the text style fields fontFamily (sans, serif, mono),
fontWeight (100 to 900 in steps of 100), fontSize (1 to 1000),
lineHeight (0.5 to 5), textAlign (left, center, right), textWrap
(none, wrap) and overflow (visible, clip); other values are refused. Any layer also takes hidden and locked (true or false): a hidden layer is not drawn or exported, and a locked one cannot be picked or moved on the canvas. Rectangles and images also take radius (0 to 10000), stroke (#rgb or #rrggbb) and strokeWidth (0 to 1000). Delete uses {"op":"delete","id":"<node-id>"} and
reorder uses {"op":"reorder","order":["<id>", …]}. Keep the IDs of existing
nodes. The file may be at most 1 MiB; other top-level keys are refused before
the request (unknown design field "extra").
hero.json
apply changes the live canvas seen by browsers authorized for live reads,
and works even when no browser has it open. Shared-only readers keep seeing
their shared snapshot. Changing the shared pin does not push replacement
document state to an already-open shared-only socket; read again or reopen. Every successful apply
records a new version. Re-applying the same file is not a no-op: upserting the
same nodes again still updates the canvas state and records another version.
Use --file - to read stdin. An
unknown node type or malformed node returns 400 invalid Design update.
Read the canvas
--version 0 (the default) reads the latest canvas for callers with current
Edit permission plus both CLI pages:read and pages:write scopes
(or pages:*, *, or an unscoped full-role token), and separately authorized workspace OWNER/ADMIN readers. Ordinary
Read grantees receive only the shared version, and 404 until one is shared. A positive --version N is
limited to that shared pin for shared-only readers. Non-admin Page owners
and Edit grantees narrowed to pages:read credentials are shared-only too. Foreign
administrator access is audited; a read-scoped administrator credential can read the latest
canvas and history but cannot write. With a selected retained version, the
version and latest_version fields both report that version; use
page design versions for the latest version visible to the caller.
can_share is true only for the Page’s owner with write rights, the same rule
page design share enforces.
Save and list versions
snapshot (alias save) records the live canvas as a new version even when it
is unchanged since the last one, and it has no idempotency key: a retry after a
lost reply adds a second version with the same content, so read versions
before sending it again. Take latest_version from versions whenever
a command below needs the latest version.
Share a version
404 design not found.
Comment on a node
Use the latest version frompage design versions (3 in this walkthrough):
--version must be the latest version, and --node must exist in it;
--quote, when given, must equal the node’s name or text. Otherwise the
server returns 409 Design changed; reload and reapply. comments returns
{"comments":[…]} with up to 500 comments.
With --send-to-agent, the comment is queued for the agent connected through
page design agent and its status is pending. The agent’s crew must be
allowed by the workspace artifact policy.
Otherwise delivery is refused with This agent's crew is not allowed to create artifact projects in this workspace. The check applies to Design as well, even
though the message names projects. Add --wait to also deliver
the task to that connected chat and wait for the agent’s answer, as the editor
does. --wait-timeout (default 15m) bounds the wait; the task stays queued
when it runs out. Without a connected chat, --wait exits with code 2 and
names the page design agent command. See
page artifact comment --wait
for the full behavior.
Restore a version
restore never rewrites history: it copies the selected version into the live
canvas and records it as a new version. Version 1 is the empty canvas from
create, so restoring it removes every node from the live canvas (get then
returns "nodes": []) and makes it the latest version. Comments on title-1
now fail with 409 because the node no longer exists. To continue, apply
hero.json again (this records version 5) and use the new latest version.
Connect an agent chat
403 current Design edit permission required. get then
reports the same origin to the owner.
Watch the permitted view
--count 0
(the default) watches until interrupted. Current Edit permission plus both CLI
pages:read and pages:write scopes (or pages:*, *, or an unscoped full-role token), and separately authorized
workspace OWNER/ADMIN access permit live document updates. Foreign administrator
access is audited. Non-admin Page owners/Edit grantees narrowed to pages:read are
shared-only: the shared snapshot and presence, without live document updates.
Before a shared pin exists, the socket can upgrade and deliver presence, but
its initial sync closes with 1008 Design permissions changed; watch reports
that close as an error if it reaches it; --count can finish on presence frames
before observing the close. A live agent run reads Design through
the design_get tool instead; with CREWSHIP_AGENT_TOKEN set, watch is
refused.
Native Craft documents
Native Craft keeps a Word document as whole-document versions. One holder at a time owns the edit lease; saves need the current lease generation.Check availability
availability never fails for a missing artifact; it reports false values.
Run it first. enabled is false when the instance switch is off (the other
human commands then report HTTP 503 and the server error text), and also when
the artifact is not a native document or you cannot read it (then expect HTTP 403;
connect reports API error (403): native Craft access denied).
Read the shared preview
craft version, craft versions and the read action of craft connect need
edit rights or the workspace owner or admin read rule, and otherwise answer 403.
Edit with a lease: acquire, read, save, release
craft connect opens one human session, prints its public session_id, then
reads one JSON action per stdin line and prints one response per action. The
private session token stays in the process, and the session ends when the
command exits.
Several action fields come from earlier responses, so feed the actions one at a
time: start the command in a terminal, type one line, read the response, then
type the next line. A script does the same by keeping the command’s stdin open
(for example a shell coprocess or a named pipe) and writing each line only
after it has read the previous response. A file written in advance works only
for actions that need no response values, such as status.
-
Type
{"action":"acquire"}. The lease view comes back:holder,mine,generation,expires_at,can_edit,can_writeand any pendinghandoff_requested_by. Notegeneration. -
Type
{"action":"read"}. The response holdsversion,bytes(the document, base64),applicationId,enginePin, editor bundle fields andquota(usedBytes,limitBytes,warning,retention). Noteversion,applicationIdandenginePin. -
Edit the decoded document, then type one
saveline: -
Type
{"action":"release","generation":"<generation>"}to give the lease back. End of input does not save or release.
Other actions:
status (lease view), acquire-explicit, renew (needs
generation), import, restore and reconcile (snapshot actions),
share (publish an existing version as the preview), reauthorize and
watch (follow the live event stream; later input lines are ignored). See
crewship craft for the route of each action and the snapshot
fields.
Generations and versions are positive decimal strings. Unknown fields are
refused, control lines are limited to 16 KiB and one connection accepts at most
4096 actions. A failed action stops the command; nothing is retried
automatically.
Hand off the lease
The person who wants the lease sends{"action":"request-handoff"} and gets a
request_id. The current holder then sends:
Initialize an empty artifact as Word or Sheet
pages:write. The native file is not a .docx or .xlsx file: it is the
editor’s native document, a single JSON object (1 byte to 32 MiB) that the
instance’s profile for that application validates; anything else is refused.
--application is word (the default, wordcraft) or sheet (gridcraft);
any other value exits 2 before a request. The command prints session_id,
application_id, page_id, generation and version ("1"), holds the new
lease, and then reads actions from stdin one line at a time exactly like
connect; use the printed generation, page_id and session_id in them.
With --file - the document is read from stdin and no actions follow. An empty
file fails before any request.
Start, check and stop an agent task
instruction saves your text in a new private chat without an agent turn and
prints the chat_id and message_id for start. start refuses an ordinary
chat message or a group chat message with 403, and needs explicit
--whole-document consent; without it the command stops with
native agent start requires explicit --whole-document=true consent. Success
returns {"work_id":"<work-id>","status":"queued"}: queued, not saved.
status reads the task’s recorded outcomes. stop revokes the agent’s mandate
on the artifact and returns grant_revoked, lease_retired,
cancel_requested, stopped and stop_pending. Stop cannot take the lease
from a human holder.
Craft errors
Human native operations preserve the HTTP status and server error text after redacting the private session token. A typical refusal isAPI error (503): native Craft unavailable. The structured error envelope can
include status, detail and extensions; lease conflicts can add the current
holder, and proposal conflicts can add their state. Exact detail depends on the
refused operation. The table describes the HTTP refusal, rather than promising a
fixed status-only message:
Native agent task refusals deliberately omit their potentially private server
body. These commands keep
native HTTP <status> with the classified exit code;
for example, native HTTP 503 exits with 7. This status-only form is separate
from the human operations above.
The local initialize --file size check reports
native document must contain 1 to32MiB of native bytes when the file is empty
or larger than 32 MiB, before native initialization.
Mooring connect
The transport-specific errors listed below remain unclassified exit code1.
Their structured stderr envelope contains only message and exit_code; a
refused WebSocket upgrade does not expose its HTTP status or server body.
Earlier login, workspace or token-host checks can still return their own
classified errors. Do not infer an HTTP status from Mooring connection rejected.
crewship mooring connect joins a Mooring collaboration session that
crewship mooring session admitted. It needs a human login; an agent token is
refused before any request.
connection_ref with --connection. --file holds one
original JSON frame per line (- reads stdin); the first is the original
session_join with its one-use ticket. Each frame is limited to 256 KiB. Server
frames print as JSON lines by default and with -f json or -f ndjson, or as
YAML documents with -f yaml.
A pending frame is not a saved change, and the command creates no receipts.
Keep your original frames to retry them. The transport contract is in
Mooring session transport.