Share Bundles

Export a self-contained snapshot of your skill tree as a single JSON file. Anyone with the file or URL can preview your skills and install the ones they want — no registry access required.

What is a Bundle?

A share bundle is a portable JSON artifact produced by gaia share. It travels anywhere — as a file, a URL, or piped through stdout — and carries everything a recipient needs to see your skills and install them locally.

Bundles are producer-heavy, consumer-light by design. All resolution work happens at gaia share time. The consumer's renderer trusts the bundle's metadata completely, so the preview always reflects the sharer's actual tree regardless of what the consumer has installed.

A bundle can span skills from multiple repositories and still present as one unified tree at the consumer side.

Quick start Generate your bundle and share the file with a teammate:
shell
gaia share
# → generated-output/share/<user>-share-bundle.json

# Teammate installs from the file
gaia install ./marco-share-bundle.json

# Or from a URL
gaia install https://example.com/marco-share-bundle.json

Bundle Anatomy

Every bundle carries three payloads. Understanding them helps when debugging install failures or building tooling on top of bundles.

Part 1
Tree Snapshot
The sharer's unlockedSkills array plus stats — a verbatim copy of skill-tree.json. Skills are identified by their canonical or named IDs.
Part 2
Install Manifest
A flat list of installable skills, each pointing to its source repository via a blob/branch/subpath GitHub URL. Only named skills with a resolvable links.github appear here.
Part 3
Skill Metadata
Pre-resolved name, level, type, and prerequisite edges for every skill in the tree. Lets the consumer render a faithful preview without touching the sharer's registry.

gaia share

Produces the share bundle for the current user. Run it inside a Git repo where you have already run gaia init.

shell
# Write bundle to generated-output/share/<user>-share-bundle.json
gaia share

# Print bundle JSON to stdout (useful for piping)
gaia share --stdout

# Upload to a server and get a sharable URL
gaia share --stdout | curl -X POST https://your-host/api/bundles -d @-

The two-pass build process:

01
Resolve skill metadata
For each unlocked skill, the producer looks up named-skills.json for the named entry, then falls back to gaia.json for the canonical entry. Name, level, type, and genericSkillRef are recorded.
02
Translate prerequisites to owned edges
Canonical prerequisite IDs are translated into the IDs actually owned by the sharer (named variants included). This lets the consumer render a realistic dependency tree using only the sharer's skills, not the full registry graph.
03
Build install manifest
Only named skills with a resolvable links.github (or suiteComponents) are included. Tree/directory-view GitHub URLs (/tree/) are automatically normalized to /blob/ so the installer can resolve them.

Flags

Flag Default Description
--stdout off Print the bundle JSON to stdout instead of writing to a file. Useful for piping to curl, jq, or other tools.
--user <handle> whoami Override the username. Defaults to the handle set by gaia init --user.

gaia install <bundle>

gaia install detects a bundle argument by shape: a .json file path or an http(s):// URL is treated as a bundle, not a named-skill ID.

shell
# Install from a local file
gaia install ./marco-share-bundle.json

# Install from a URL
gaia install https://example.com/marco-share-bundle.json

# Named-skill IDs are NOT bundles — they go through the registry
gaia skills install marco/gaia-curate

When called with a bundle reference, gaia install first renders the sharer's tree preview, then walks the guided install flow.

Install Flow

After rendering the preview, the consumer is prompted with four choices:

KeyEffect
[A] All Install every skill in the manifest.
[P] Pick Enter a space- or comma-separated list of item numbers to install selectively.
[V] View only Preview the tree without installing anything. Safe default.
[Q] Quit Exit immediately. Nothing is installed or downloaded.

After installation completes, a summary line prints with four counts: installed, skipped, unresolved, and failed.

example session
Shared skill tree from marco:

marco
└── ○ research
    ├── ◇ gaia-curate  2★
    └── ◇ gaia-curate-chain  3★

3 installable skill(s):
   1. marco/research        (1★) → https://github.com/mbtiongson1/…
   2. marco/gaia-curate     (2★) → https://github.com/mbtiongson1/…
   3. marco/gaia-curate-chain (3★) → https://github.com/mbtiongson1/…

Install? [A]ll  [P]ick  [V]iew only  [Q]uit: p
Enter numbers to install (space/comma separated): 2 3

Summary:
  installed:  2  marco/gaia-curate, marco/gaia-curate-chain
  skipped:    1  marco/research
  unresolved: 0

Non-TTY / Automation

When stdin is not a TTY (CI runners, scripts, piped commands), gaia install automatically defaults to view-only mode. No interactive prompt is shown and nothing is installed.

Automation note To install all skills non-interactively in a CI pipeline, you must pass the intent explicitly. The --auto all flag (when available) bypasses the TTY check. Without it, automation always gets view-only output.

This design prevents accidental installs when bundles are processed in scripts or agent pipelines that pipe bundle JSON through gaia install.

Resolution Strategy

For each skill in the install manifest, gaia install tries two paths in order:

#StrategyWhen it applies
1 Registry resolution — reuse gaia skills install path The consumer's registry knows about the skill ID (resolve_named_skill_reference succeeds). Fastest path; works when sharer and consumer share the same registry.
2 Direct source URL — install from bundle's github field The skill is not in the consumer's registry (foreign skill, multi-repo bundle). The installer fetches directly from the blob/branch/subpath URL stored in the bundle's manifest entry.
Unresolved Neither strategy succeeded (registry miss + no github URL in manifest). Appears in the unresolved summary count. Usually means the source repo is private or the named skill has installable: false.

Because the direct-URL path reuses the same _install_single code as the registry path, all the same blob/ URL requirements apply — tree/ URLs in the manifest are automatically normalized to blob/ by the producer before the bundle is written.

Bundle Format Reference

The top-level shape of a bundle JSON:

JSON — top level
{
  "kind":          "gaia-share-bundle",   // always this literal
  "bundleVersion": "1",
  "generatedAt":   "2026-06-12T13:00:00Z",
  "sharer":        "marco",
  "sourceRepo":    "https://github.com/mbtiongson1/gaia-skill-tree",
  "tree": { … },          // Part 1 — tree snapshot
  "skillMeta": { … },    // Part 3 — pre-resolved metadata
  "install": [ … ]       // Part 2 — install manifest
}

tree

FieldTypeDescription
userIdstringGitHub handle of the sharer.
updatedAtstringISO 8601 timestamp from the sharer's skill-tree.json.
unlockedSkillsarrayArray of { skillId, level } objects — verbatim from the sharer's tree.
statsobjectAggregate stats snapshot (skill count, star totals, etc.).

skillMeta

An object keyed by skill ID. Each value:

FieldTypeDescription
namestringHuman-readable display name.
levelstringStar level (e.g. "2★").
typestringTier: basic, extra, unique, or ultimate.
namedbooleanTrue if this is a Named Skill (contributor/slug ID).
genericRefstring | nullThe canonical skill ID this named skill implements.
prereqsstring[]Owned-skill edges (translated from canonical prerequisite IDs to IDs the sharer actually holds).

install (manifest entry)

FieldTypeDescription
idstringNamed skill ID (e.g. marco/gaia-curate).
namestringDisplay name.
levelstringStar level.
typestringTier.
githubstringblob/branch/subpath URL for the skill's source. Present on individual (non-suite) skills.
suiteComponentsstring[]Component skill IDs for suite skills. Absent on individual skills.
genericSkillRefstringThe canonical ID this implementation fulfills.

Known Issues

No static copy-link page (Issue #128)

The planned docs/share/ page — a static web UI where you paste a bundle URL and get a shareable copy-link — is a deferred fast-follow tracked in Issue #128. Until it ships, share bundles must be distributed as raw files or URLs pointing to raw JSON.

Private-repo skills resolve as unresolved

If a Named Skill's source repository is private, the direct-URL path fails and the skill lands in the unresolved count. The producer still includes the skill in skillMeta for preview rendering, but the manifest entry is omitted because there is no public source to fetch from.

Suite skills have no install directory

A suite skill (one with suiteComponents) installs by iterating its components — it has no directory of its own. Accordingly, the manifest entry carries suiteComponents instead of github. Do not flag suite manifest entries as "missing github URL."

Note Skills with installable: false in their registry entry frontmatter are intentionally excluded from the install manifest. They still appear in skillMeta for the preview tree.