These guides are primarily for agent readers. They explain how agents use Sails. If you are a person, start at sails.app or Add Sails.

Share a directory with another repo

share publishes a directory so other repositories can copy it in. It tracks the source branch tip the way publish tracks a site, but consumers do not update on autosave. Someone (or a cron) must run share pull.

This is not a public HTTP URL. For a site people open in a browser, use Publish a site. This is not upload / download (those are one-time links for a person on a laptop).

Create requires repository owner. Pull requires write access on the consumer repository.

Done looks like

share list in the source repo prints JSON that includes a share id. In the consumer repo, share pull SHARE_ID dest/ writes files into dest/. share status SHARE_ID in the consumer shows whether the last pull matches the source tip. Later share pull SHARE_ID (no dest) overwrites that same binding.

Worked example: vendor a tools/ folder

Job: repo A has tools/ that repo B should use. Source checkpoint does not fan out. B pulls when it wants a new copy.

1. Source repo (owner)

The path must be under $HOME, on the branch tip, and non-empty. Autosave usually already checkpointed.

share create --path tools --policy 644

--policy 644 lets any authenticated user pull (cross-repo). Default 600 is source owner only, so another repository cannot pull.

Commands print JSON to stdout. Copy the share id from that object.

share list
share status SHARE_ID

share list is JSON (an array). Use the same id on the consumer.

2. Consumer repo (write access)

First pull requires a destination path. It must be a folder you can write.

share pull SHARE_ID vendor/tools

Done: vendor/tools exists and matches the source tip at pull time. share bindings in this repo lists the install (share id → dest path).

After the source repo edits tools/ and autosave moves the tip:

share pull SHARE_ID

Omitting dest reuses the bound path and overwrites. There is no merge.

3. Keep it current (optional)

Pulls stay manual unless you schedule them. Owner-only, same as other cron:

echo 'share pull SHARE_ID' | cron '15 6 * * *'
crontab -l

See Run something every morning. There is no automatic fan-out on source checkpoint.

Flags and commands

share help
CommandWhat it does
share create [--path PATH] [--branch B] [--policy MODE]Owner. Share that folder on that branch. Default path is cwd. Default policy 600.
share listShares created in this repo (JSON)
share update ID --policy MODEChange who may pull
share delete IDDrop the share. Existing consumer copies stay on disk until someone deletes them
share pull ID [DEST]Consumer. First time needs DEST. Later pulls may omit it
share bindingsInstalls in the current repo
share status IDTip vs last pulled

Policies (who may pull), same octal model as publish:

PolicyWho can pull
644Any authenticated user (cross-repo share)
640Source repo owner or default-group members
600Source repo owner only (default)

--branch pins which source branch tip the share tracks. Omit it to use the current branch.

Failure modes

What you seeWhat it meansWhat to do
Create deniedOwner-onlyAn owner runs share create, or elevate that goal
Consumer cannot pullPolicy too tight, or no write access hereSource: share update ID --policy 644. Consumer: you need write in this repo
Pull asks for dest-pathFirst install in this reposhare pull ID vendor/tools
Consumer still has old filesPulls are manualshare pull ID. Or cron. Do not wait for autosave
Empty / invalid pathCwd or --path not a non-empty folder under $HOMEShare a real directory that already has files on the branch tip
You publish create for a library folderThat is an HTTP mountshare create if the job is another repo copying files
You used upload for a repo-to-repo copyUpload is a person on a laptopshare create / share pull
You expected git historyShare copies the directory contentsUse Sync with GitHub if you need a git remote

repo copy-path is a one-shot membership-gated graft. It has no share id and no pull tracking. Use share when the consumer should refresh later.

See File transfer when the other side is a browser, and Publish a site when the other side is HTTP.