Documentation Getting started

Getting Started

The recommended way to install and use Dalo is through your local coding agent. Paste this into the agent you want to set up:

Install Dalo, the agent skill manager.

The agent installs the binary and bundled assistant, connects its skill folder, and checks the result. Then keep talking to it: “Add my team's skill repository,” “Update my skills and show me what changed,” or “Check what needs attention.” You do not need to learn Dalo's commands. Its approval, audit, and ownership checks apply when your agent uses Dalo, keeping catalog approvals and conflicts visible while sync preserves your own files. See Use Dalo through your agent for everyday requests, existing setups, and how those protections work.

The rest of this guide is the command-line walkthrough from a fresh install to agents that read your team's skills. If you own the repository those skills come from, read the team repository guide as well.

Before you start:

Pick your starting point

You do not need a team repository or a clean machine to begin. Find the row that matches your situation:

Your situation Start here
You want to look around without risk Explore without touching your agent folders, then come back
Your team already has a skill repository Continue with step 1 below
It is just you, with no team repository yet Steps 1 and 2, then the catalog path in step 3
Skills already live in your agent folder Steps 1 and 2, then adopt them — Dalo leaves them untouched until you do
Your project installed skills with skills.sh Migrate a skills.sh project
The skills belong to one repository, not your whole machine Project installations

1. Initialize the store

dalo init

The store is Dalo's local database: source checkouts, the private local source, lockfiles, approvals, and target state. It lives in ~/.dalo unless --store or DALO_STORE says otherwise. Your agent folders are output, never input; nothing in them is read back into the store by accident.

init finishes by printing the next three steps, which are the next three sections of this page.

2. Connect an agent

Ask Dalo what it can see:

dalo target detect

The report lists every known target, the path it would use, whether that path exists, and whether it is already linked. Then link the agents you use:

dalo target link claude
# or: dalo target link codex
# or: dalo target link openclaw
# or: dalo target link hermes
# or: dalo target link opencode
# or: dalo target link cursor

A known target uses its default directory; pass a path to override it. The generic target always needs an explicit path:

dalo target link generic /path/to/agent/skills

Linking records a directory. It does not move or delete anything yet.

3. Add your team's skill repository

A source is a Git-backed collection of skills. A team source is trusted by default, so its skills do not need per-skill approval:

dalo source add company git@github.com:acme/agent-skills.git

Dalo clones it, discovers the skills under skills/, and runs a deterministic security preflight over every one of them before anything is linked.

If your team repository also pins public catalogs in a dalo.toml manifest, those arrive automatically as company.<catalog-id> sources. They are untrusted, so their skills wait for your approval — see pending approval below.

No team repository yet? Skip source add. A public catalog gives you real skills to start from, and you pick only the ones you want:

dalo source add-catalog sebastian https://github.com/sebastian-software/skills.sebastian-software.com.git
dalo source inspect sebastian
dalo source select sebastian effective-web

A selected catalog skill is untrusted until you approve it, which is the pending approval state below. To publish a repository for your team later, follow the team repository guide.

4. Sync

dalo sync

sync refreshes clean tracking sources, resolves one approved skill set, and links that set into every linked target:

target[claude]: …/skills
applied  create     target[claude]:/incident-review -> store:/sources/company/checkout/skills/incident-review
applied  create     target[claude]:/release-notes -> store:/sources/company/checkout/skills/release-notes
synced: 2 skills across 1 target (2 created)
security preflight: deterministic checks only

Dalo creates symlinks it owns. It never overwrites an unmanaged directory or a symlink it did not create; anything it cannot do safely is reported instead.

Your agent now reads those skills from the folder it already uses.

5. Read the state

Two commands answer two different questions.

dalo status
dalo next

status is the full picture: sources, targets, active skills, pending approvals, unlinked skills, materialization blocks, resolution diagnostics, and lock drift. dalo status --check exits non-zero when anything needs attention, which is what you want in a script or a pipeline.

next is the opposite: one summary and exactly one copyable command.

Dalo
  store: …
  initialized: yes
  linked targets: 1
  sources: 4
  active skills: 4
  pending approvals: 0

Next: dalo status
  Linked targets contain unmanaged skills; review detailed status before synchronizing.

In a terminal, bare dalo prints the same summary. Use dalo next explicitly when output is piped or scripted.

6. Three words status uses, and the command that clears each

The first time status says something surprising, it is almost always one of these three. The transcripts below are real output from a linked claude target.

Pending approval

A skill is available but untrusted, so Dalo will not link it. Catalog sources and catalogs pinned by a team manifest start here by design.

pending approval:
  review-helper -> public:review-helper (run: dalo approve skill public:review-helper)

sync still does all the other work and repeats the same line at the end:

synced: 2 skills across 1 target (2 unchanged)
pending approval: public:review-helper (run: dalo approve skill public:review-helper)
security preflight: deterministic checks only

Read the skill first — dalo audit public:review-helper prints the deterministic findings and the exact content hash — then run the command status gave you:

dalo approve skill public:review-helper
dalo sync

Approvals are per skill, per machine, and bound to exact content. They are never inherited from a teammate and never granted by a sync.

Shadowed

Two sources offer the same skill name. Dalo links exactly one of them and keeps the other visible instead of discarding it:

unlinked skills:
  release-notes -> company:release-notes reason=shadowed by=personal:release-notes
resolution diagnostics:
  shadowed: skill `company:release-notes` is unlinked because `personal:release-notes` wins the same slot

The lower priority number wins. If you want to change the winner, first inspect the source authority with dalo source list --json, then preview the source-wide priority change:

dalo --dry-run source priority company 1

The built-in local source priority is fixed. If declared_by in the source list names a team source, that source's catalog settings belong to its dalo.toml and must be changed through the team's workflow.

If you choose that change, apply it and then preview the full store sync under the new priority before changing target links:

dalo source priority company 1
dalo --dry-run sync

The two dry-runs alone do not compose: the sync preview still uses the current priority. If both variants should stay installed side by side, namespace one source only if changing the installed name of every skill from that source is acceptable. Preview the namespace change, apply it if you choose it, then preview the full store sync under the new namespace. A namespace produces names such as acme__release-notes; it does not rename just the colliding skill or edit references. Team skills with a namespace still receive upstream changes through their usual refresh and sync.

Conflict

Dalo wants a slot that is already occupied by a real, unmanaged directory — usually a skill an agent wrote directly into its own folder.

materialization blocks:
  target[claude]:/standup-notes: real unmanaged entry exists at target slot
unmanaged skills:
  standup-notes -> target[claude]:/standup-notes (adopt: run `dalo adopt 'standup-notes'` to copy it into the local source; use `dalo adopt 'standup-notes' --replace` to replace the original)

sync reports the block and leaves your file alone:

blocked  conflict   target[claude]:/standup-notes -> store:/sources/company/checkout/skills/standup-notes (real unmanaged entry exists at target slot) …
synced: 4 skills across 1 target (3 unchanged, 1 blocked)

For a real unmanaged directory, first inspect exact IDs and paths with dalo --json resolve list. Then choose the option that matches what you want:

dalo resolve adopt <id>              # copy it to the local source; leave original in place
dalo resolve adopt <id> --replace    # also replace this directory with a Dalo link
dalo resolve keep <id>               # retain it unmanaged at this target slot

Adoption is audited and makes a local snapshot, so it no longer follows the old installer or upstream. Its dry-run does not create that local skill for a following sync preview. Applying adoption can make the local copy win over a same-named managed source across other linked agents. Review the adoption audit and exact copy or replacement effect, apply only the choice you intended, then inspect status and preview the full store sync before any further target changes. Without --replace, the original stays in place and may continue blocking that target slot. keep records the unmanaged choice; the managed skill remains unavailable at that occupied slot. A foreign symlink is not an adoptable directory: preserve it and use the migration guidance for foreign entries only when that handover is explicitly requested. Sync has no per-target filter.

7. Keep it current

Run dalo sync to fetch and apply updates from clean tracking team sources. Personal catalog pins stay on their selected versions until you request an update.

For recurring updates, ask your agent or host to automate this command for the chosen store:

dalo --store <store-path> --json sync --check

Choose the cadence and notifications in that automation. --check still applies the sync; it returns a failure when the result needs review. Pending approvals, security findings, local edits, and conflicts require attention. See Automate updates for the scope and update-policy choices. Existing autosync installations remain supported in Dalo 1.x.

For a focused health check:

dalo doctor

Explore without touching your agent folders

Everything above also works in a throwaway store with a temporary folder as the target. Nothing in this section writes to a real agent directory.

A sandbox store

export DALO_STORE="$(mktemp -d)/store"
target_dir="$(mktemp -d)/skills"

dalo init
dalo target link generic "$target_dir"

A local skill

mkdir -p "$DALO_STORE/local/skills/review"
cat > "$DALO_STORE/local/skills/review/SKILL.md" <<'EOF'
# Review

Check behavioral regressions before style nits.
EOF

dalo status
dalo sync
ls -la "$target_dir"

The local source is private to your machine: experiments and overrides live there. status may show a lock drift block until the next sync records the new skill; see Lock Drift.

A local team source

A local Git repository works as a source, so this needs no network access:

TEAM_REPO="$(mktemp -d)/team-skills"
mkdir -p "$TEAM_REPO/skills/release-notes"
cat > "$TEAM_REPO/skills/release-notes/SKILL.md" <<'EOF'
# Release Notes

Summarize user-visible changes first.
EOF

git -C "$TEAM_REPO" init
git -C "$TEAM_REPO" add .
git -C "$TEAM_REPO" -c commit.gpgSign=false -c user.email=test@example.com -c user.name='Test User' commit -m initial

dalo source add company "$TEAM_REPO"
dalo source list
dalo sync

Sync still audits team content and blocks unaccepted high or critical findings.

A local catalog source

A catalog offers many skills and installs only what you select. This is where pending approval comes from:

CATALOG_REPO="$(mktemp -d)/catalog-skills"
mkdir -p "$CATALOG_REPO/skills/review-helper"
cat > "$CATALOG_REPO/skills/review-helper/SKILL.md" <<'EOF'
# Review Helper

Check behavioral regressions before style nits.
EOF

git -C "$CATALOG_REPO" init
git -C "$CATALOG_REPO" add .
git -C "$CATALOG_REPO" -c commit.gpgSign=false -c user.email=test@example.com -c user.name='Test User' commit -m initial

dalo source add-catalog public "$CATALOG_REPO"
dalo source inspect public
dalo source select public review-helper
dalo status

Review the pending skill, grant only that skill, then sync it:

dalo audit public:review-helper
dalo approve skill public:review-helper
dalo sync

source add, source select, and approve skill run deterministic local preflight checks. sync repeats them against the exact content about to be linked and blocks unaccepted high or critical findings from those checks or a compatible cached review. sync does not start an agent reviewer, and a passing preflight is not a safety guarantee.

An optional semantic review by an agent needs an installed Claude or OpenCode CLI on PATH and may send the skill's contents to that provider, so it is not part of the core flow:

dalo audit public:review-helper --reviewer auto

To accept a known risk for one exact content hash and finding set, give a reason:

dalo audit public:review-helper --accept-risk "reviewed pinned upstream installer"

Changing any file, adding findings, or upgrading an audit or review engine invalidates that acceptance. dalo approve list shows the local trust rules; broader source, author, and org approvals exist when that is the intended policy.

Leaving the sandbox

unset DALO_STORE

The next command uses your real store again.

Adopt a skill an agent wrote

When an agent creates a useful skill directly in its own folder, status lists it under unmanaged skills. Copy it into the private local source:

dalo adopt release-notes

Adoption prints a local security preflight before it copies anything. Replacing the original folder with a Dalo-owned symlink is a separate explicit step:

dalo adopt --replace release-notes

Dalo does not commit adopted work automatically. You decide when an experiment is ready to move into the reviewed team repository. When it is, promote opens a pull request against that repository instead of pushing to it:

dalo --dry-run promote release-notes --target company
dalo promote release-notes --target company

company is the ID of the team source. The real run needs an authenticated GitHub CLI (gh); see dalo promote for forks and the cases it blocks.

Where to go next

Source: docs/getting-started.md