Droploft v2 CLI — Document Skill
A drop is a single document. It belongs to exactly one loft. This skill covers everything that happens to drops after they are created.
Concepts
loft_id— required for write ops; defaults toprofile.loft_idset byloft +switch.kind—markdownorhtml. The CLI auto-detects from extension and content prefix.status—processing(just uploaded) →published(worker finished optimization).- A successful upload returns a
share_tokenandshare_url(default share is enabled at creation). - Publish is asynchronous — the CLI polls
GET /v1/tasks/:iduntilstatus∈{success, failed, cancelled}.
Layer 1 flows
Upload a file
droploft doc +upload ./report.md
droploft doc +upload report.html --title "Q4 Plan" --loft <loft-id>
droploft doc +upload README.md --no-wait # return as soon as publish enqueues
Sequence:
- Read file, hash, derive title (override with
--title). POST /v1/documents→{document_id, upload_url, share_token, share_url}.- PUT raw bytes to the presigned URL with
content-type: text/html|text/markdown. POST /v1/documents/:id/publish→{task_id}.- Poll
GET /v1/tasks/:task_id(default deadline 120 s).
List drops in a loft
droploft doc +list # uses profile.loft_id
droploft doc +list --loft <id> --limit 20
Layer 2 resource verbs
droploft documents list # current loft, scriptable
droploft documents get <doc-id> # detail incl. workspace/owner/share
droploft documents content <doc-id> # latest published content
droploft documents share-link <doc-id> # current share-link settings
droploft documents update-share <doc-id> --data '{"share_enabled":false}'
droploft documents publish <doc-id> # enqueue publish/optimize
droploft documents delete <doc-id> # move to trash
droploft documents trash # list trashed drops
droploft documents restore <doc-id> # restore from trash
droploft documents purge <doc-id> # permanent delete
droploft documents shared-with-me
Combine with --format json --jq '.[].id' to feed pipelines.
Patterns
Idempotent publish from CI
ID=$(droploft doc +upload ./build/index.html --no-wait --format json | jq -r .data.document_id)
# … later, after build settles
droploft documents publish "$ID"
Disable share for a sensitive drop
droploft documents update-share <doc-id> --data '{"share_enabled":false}'
Diagnose a failed publish
droploft tasks list --format table # find the failing task_id
droploft tasks get <task-id> # full row incl. error_message
droploft tasks retry <task-id> # re-enqueue
Common errors
| Type | Meaning | Recovery |
|---|---|---|
auth_required (exit 3) |
token missing/revoked | droploft auth login |
not_found (exit 4) |
drop doesn't exist or no read access | check documents list / loft membership |
conflict (exit 5) |
save race | retry with the latest base revision |
validation (exit 2) |
bad body — check droploft schema get documents.create |
Limits & gotchas
- Files larger than the workspace plan trigger HTTP 413; envelope
error.messageincludes the upgrade hint. update-sharebody shape is{share_enabled, password?, expires_at?, max_views?}.- After a
delete, the doc is hidden fromdocuments listbut remains indocuments trashuntil purged.