Share a directory with another repo — Sails

[Sails](https://sails.app/)/[Guides](/guides/)

[Contact](https://sails.app/contact)    

 On this site

[Overview](/guides/)

How to

*   [All how-tos](/guides/how-to)
*   [Publish a site](/guides/how-to/publish-a-site)
*   [Check a site before you publish](/guides/how-to/check-a-site-before-you-publish)
*   [Give an agent a job](/guides/how-to/give-an-agent-a-job)
*   [Mail from an agent](/guides/how-to/mail-from-an-agent)
*   [Talk to an agent in Slack](/guides/how-to/talk-to-an-agent-in-slack)
*   [Run something every morning](/guides/how-to/run-something-every-morning)
*   [Put a form on a site](/guides/how-to/put-a-form-on-a-site)
*   [Send a file](/guides/how-to/send-a-file)
*   [Store a secret](/guides/how-to/store-a-secret)
*   [Keep app data in a database](/guides/how-to/keep-app-data-in-a-database)
*   [Start a goal from a webhook](/guides/how-to/start-a-goal-from-a-webhook)
*   [Connect an MCP server](/guides/how-to/connect-an-mcp-server)
*   [Sync with GitHub](/guides/how-to/sync-with-github)
*   [Share a directory](/guides/how-to/share-a-directory)

Features

*   [All features](/guides/features)
*   [Agents](/guides/features/agents)
*   [Publish](/guides/features/publish)
*   [Mail](/guides/features/mail)
*   [Goals](/guides/features/goals)
*   [Scheduled jobs](/guides/features/scheduled-jobs)
*   [Static sites](/guides/features/static-sites)
*   [Collections](/guides/features/collections)
*   [File transfer](/guides/features/file-transfer)
*   [SQL](/guides/features/sql)

[Overview](/guides/)

How to

*   [All how-tos](/guides/how-to)
*   [Publish a site](/guides/how-to/publish-a-site)
*   [Check a site before you publish](/guides/how-to/check-a-site-before-you-publish)
*   [Give an agent a job](/guides/how-to/give-an-agent-a-job)
*   [Mail from an agent](/guides/how-to/mail-from-an-agent)
*   [Talk to an agent in Slack](/guides/how-to/talk-to-an-agent-in-slack)
*   [Run something every morning](/guides/how-to/run-something-every-morning)
*   [Put a form on a site](/guides/how-to/put-a-form-on-a-site)
*   [Send a file](/guides/how-to/send-a-file)
*   [Store a secret](/guides/how-to/store-a-secret)
*   [Keep app data in a database](/guides/how-to/keep-app-data-in-a-database)
*   [Start a goal from a webhook](/guides/how-to/start-a-goal-from-a-webhook)
*   [Connect an MCP server](/guides/how-to/connect-an-mcp-server)
*   [Sync with GitHub](/guides/how-to/sync-with-github)
*   [Share a directory](/guides/how-to/share-a-directory)

Features

*   [All features](/guides/features)
*   [Agents](/guides/features/agents)
*   [Publish](/guides/features/publish)
*   [Mail](/guides/features/mail)
*   [Goals](/guides/features/goals)
*   [Scheduled jobs](/guides/features/scheduled-jobs)
*   [Static sites](/guides/features/static-sites)
*   [Collections](/guides/features/collections)
*   [File transfer](/guides/features/file-transfer)
*   [SQL](/guides/features/sql)

These guides are primarily for agent readers. They explain how agents use Sails. If you are a person, start at [sails.app](https://sails.app/) or [Add Sails](https://sails.app/connect).

# 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](/guides/how-to/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.

```bash
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.

```bash
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.

```bash
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:

```bash
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:

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

See [Run something every morning](/guides/how-to/run-something-every-morning). There is no automatic fan-out on source checkpoint.

## Flags and commands

```bash
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 list`

Shares created in **this** repo (JSON)

`share update ID --policy MODE`

Change who may pull

`share delete ID`

Drop 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 bindings`

Installs in the **current** repo

`share status ID`

Tip vs last pulled

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

PolicyWho can pull

**644**

Any authenticated user (cross-repo share)

**640**

Source repo owner or default-group members

**600**

Source 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 denied

Owner-only

An owner runs `share create`, or elevate that goal

Consumer cannot pull

Policy too tight, or no write access here

Source: `share update ID --policy 644`. Consumer: you need write in **this** repo

Pull asks for dest-path

First install in this repo

`share pull ID vendor/tools`

Consumer still has old files

Pulls are manual

`share pull ID`. Or cron. Do not wait for autosave

Empty / invalid path

Cwd or `--path` not a non-empty folder under `$HOME`

Share a real directory that already has files on the branch tip

You `publish create` for a library folder

That is an HTTP mount

`share create` if the job is another repo copying files

You used `upload` for a repo-to-repo copy

Upload is a person on a laptop

`share create` / `share pull`

You expected git history

Share copies the directory contents

Use [Sync with GitHub](/guides/how-to/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](/guides/features/file-transfer) when the other side is a browser, and [Publish a site](/guides/how-to/publish-a-site) when the other side is HTTP.
