skills: single install path — canonical skills ship with the framework
Phase D2 of plan 2026-08-19: single package, single install, single command. The framework installer already treats skills/** as a shipped, manifest-owned framework subtree, so the folded skills now install into $MOSAIC_HOME/skills with the rest of the framework — no second repository, no separate sync step: - mosaic-sync-skills (bash + powershell): the fetch machinery is gone (clone, pull, dirty-state migration, rsync from sources/agent-skills). The script now only links installed skills into runtime homes. --link-only is a compat no-op; --no-link exits having nothing to do. - catalog.ts: the sources/agent-skills fallback is dead and removed. - install.sh, launch.ts, defaults/README.md, README.md, skills/README.md: references to the second repo rewritten to describe the shipped path. Verified: clean install into a fresh MOSAIC_HOME produces 102 skills with no sources/ directory; the linker then links the selected skills into the four runtime homes with no git involvement.
This commit is contained in:
@@ -331,7 +331,7 @@ The framework is the bash-based standards layer installed to every developer mac
|
|||||||
├── bin/mosaic ← Unified launcher (claude, codex, opencode, pi, yolo)
|
├── bin/mosaic ← Unified launcher (claude, codex, opencode, pi, yolo)
|
||||||
├── guides/ ← E2E delivery, orchestrator protocol, PRD, etc.
|
├── guides/ ← E2E delivery, orchestrator protocol, PRD, etc.
|
||||||
├── runtime/ ← Per-runtime configs (claude/, codex/, opencode/, pi/)
|
├── runtime/ ← Per-runtime configs (claude/, codex/, opencode/, pi/)
|
||||||
├── skills/ ← Universal skills (synced from agent-skills repo)
|
├── skills/ ← Universal skills (shipped with the framework package)
|
||||||
├── tools/ ← Tool suites (orchestrator, git, quality, prdy, etc.)
|
├── tools/ ← Tool suites (orchestrator, git, quality, prdy, etc.)
|
||||||
└── memory/ ← Persistent agent memory (preserved across upgrades)
|
└── memory/ ← Persistent agent memory (preserved across upgrades)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ You can still launch runtimes directly (`claude`, `codex`, etc.) — thin runtim
|
|||||||
│ ├── opencode/ ← AGENTS.md, RUNTIME.md
|
│ ├── opencode/ ← AGENTS.md, RUNTIME.md
|
||||||
│ ├── pi/ ← RUNTIME.md, mosaic-extension.ts
|
│ ├── pi/ ← RUNTIME.md, mosaic-extension.ts
|
||||||
│ └── mcp/ ← MCP server configs
|
│ └── mcp/ ← MCP server configs
|
||||||
├── skills/ ← Universal skills (synced from mosaic/agent-skills)
|
├── skills/ ← Universal skills (shipped with the framework package)
|
||||||
├── skills-local/ ← Local cross-runtime skills
|
├── skills-local/ ← Local cross-runtime skills
|
||||||
├── memory/ ← Persistent agent memory (preserved across upgrades)
|
├── memory/ ← Persistent agent memory (preserved across upgrades)
|
||||||
└── templates/ ← SOUL.md template, project templates
|
└── templates/ ← SOUL.md template, project templates
|
||||||
@@ -193,11 +193,11 @@ The installer rejects unrecognized flags or positional arguments before making c
|
|||||||
|
|
||||||
## Universal Skills
|
## Universal Skills
|
||||||
|
|
||||||
The installer syncs skills from `mosaic/agent-skills` into `~/.config/mosaic/skills/`. Install, wizard finalization, and `mosaic update` automatically reconcile every canonical skill into Claude Code's `~/.claude/skills/` directory.
|
Canonical skills ship inside the framework package itself; the installer installs them into `~/.config/mosaic/skills/` together with the rest of the framework (there is no separate skills repository). Install, wizard finalization, and `mosaic update` automatically link every canonical skill into Claude Code's `~/.claude/skills/` directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mosaic sync # Full canonical catalog sync
|
mosaic sync # Relink the full canonical catalog
|
||||||
~/.config/mosaic/tools/_scripts/mosaic-sync-skills --link-only # Re-link only
|
~/.config/mosaic/tools/_scripts/mosaic-sync-skills --link-only # Re-link only (same as default)
|
||||||
mosaic skill list # Show registered, missing, dangling, and foreign entries
|
mosaic skill list # Show registered, missing, dangling, and foreign entries
|
||||||
mosaic skill register <name> # Register or repair one canonical Claude link
|
mosaic skill register <name> # Register or repair one canonical Claude link
|
||||||
mosaic skill unregister <name> # Remove one Mosaic-owned Claude link
|
mosaic skill unregister <name> # Remove one Mosaic-owned Claude link
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ set -Eeuo pipefail
|
|||||||
# MOSAIC_HOME — target directory (default: ~/.config/mosaic)
|
# MOSAIC_HOME — target directory (default: ~/.config/mosaic)
|
||||||
# MOSAIC_INSTALL_MODE — prompt|keep|overwrite (default: prompt)
|
# MOSAIC_INSTALL_MODE — prompt|keep|overwrite (default: prompt)
|
||||||
# MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING — 1 to bypass MCP check
|
# MOSAIC_ALLOW_MISSING_SEQUENTIAL_THINKING — 1 to bypass MCP check
|
||||||
# MOSAIC_SKIP_SKILLS_SYNC — 1 to skip skill sync
|
# MOSAIC_SKIP_SKILLS_SYNC — 1 to skip linking skills into runtime homes
|
||||||
#
|
#
|
||||||
# Flags (CLI args, NOT environment variables — see #869 Point-1 C2):
|
# Flags (CLI args, NOT environment variables — see #869 Point-1 C2):
|
||||||
# --allow-inactive-enforcement Explicit, per-invocation opt-out that lets the
|
# --allow-inactive-enforcement Explicit, per-invocation opt-out that lets the
|
||||||
@@ -828,7 +828,7 @@ if [[ -x "$SCRIPTS/mosaic-ensure-excalidraw" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${MOSAIC_SKIP_SKILLS_SYNC:-0}" != "1" ]] && [[ -x "$SCRIPTS/mosaic-sync-skills" ]]; then
|
if [[ "${MOSAIC_SKIP_SKILLS_SYNC:-0}" != "1" ]] && [[ -x "$SCRIPTS/mosaic-sync-skills" ]]; then
|
||||||
"$SCRIPTS/mosaic-sync-skills" >/dev/null 2>&1 && ok "Skills synced" || warn "Skills sync failed (non-fatal)"
|
"$SCRIPTS/mosaic-sync-skills" >/dev/null 2>&1 && ok "Skills linked into runtime homes" || warn "Skills linking failed (non-fatal)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -x "$SCRIPTS/mosaic-migrate-local-skills" ]]; then
|
if [[ -x "$SCRIPTS/mosaic-migrate-local-skills" ]]; then
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Agent Skills
|
# Agent Skills
|
||||||
|
|
||||||
Complete agent skill fleet for Mosaic Stack. 95 skills across 12 domains — coding, business development, design, marketing, writing, orchestration, document generation, Vue/Vite ecosystem, and more. Platform-aware — works with both GitHub (`gh`) and Gitea (`tea`) via our abstraction scripts.
|
Complete agent skill fleet for Mosaic Stack. 101 skills across 12 domains — coding, business development, design, marketing, writing, orchestration, document generation, Vue/Vite ecosystem, and more. Platform-aware — works with both GitHub (`gh`) and Gitea (`tea`) via our abstraction scripts.
|
||||||
|
|
||||||
|
This tree lives in the monorepo (`packages/mosaic/framework/skills/`) and ships inside the framework package; it is no longer a separate repository.
|
||||||
|
|
||||||
## Security Audit
|
## Security Audit
|
||||||
|
|
||||||
@@ -196,29 +198,21 @@ All skills were reviewed on 2026-02-16. Findings:
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Via npx (recommended)
|
The skills ship with the framework package. The framework installer installs them
|
||||||
|
into `~/.config/mosaic/skills/`, and the post-install step links them into each
|
||||||
|
runtime's skill directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install a single skill
|
# Install or upgrade the framework (skills arrive with it — no second repo)
|
||||||
npx skills add https://git.mosaicstack.dev/mosaic/agent-skills.git --skill nestjs-best-practices --agent claude-code
|
./packages/mosaic/framework/install.sh
|
||||||
|
|
||||||
# Install all skills
|
# Re-link installed skills into runtime homes (claude, codex, opencode, pi)
|
||||||
npx skills add https://git.mosaicstack.dev/mosaic/agent-skills.git --agent claude-code
|
mosaic sync
|
||||||
|
|
||||||
# Non-interactive (CI/scripting)
|
|
||||||
npx skills add https://git.mosaicstack.dev/mosaic/agent-skills.git --yes --agent claude-code
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:** The `.git` suffix on the URL is required for Gitea-hosted repos.
|
Operators can override any canonical skill by copying it to
|
||||||
|
`~/.config/mosaic/skills-local/<name>/` — local skills take precedence during
|
||||||
### Manual (symlink from local clone)
|
linking.
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://git.mosaicstack.dev/mosaic/agent-skills.git ~/src/agent-skills
|
|
||||||
for skill in ~/src/agent-skills/skills/*/; do
|
|
||||||
ln -sf "$skill" ~/.config/mosaic/skills/$(basename "$skill")
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adapting Skills
|
## Adapting Skills
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Link the INSTALLED canonical skills into runtime skill directories.
|
||||||
|
#
|
||||||
|
# The canonical skills ship inside the framework package itself
|
||||||
|
# (packages/mosaic/framework/skills in the monorepo) and are installed into
|
||||||
|
# $MOSAIC_HOME/skills by the framework installer — there is no second
|
||||||
|
# repository to clone. This script only maintains the runtime symlinks.
|
||||||
|
|
||||||
MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}"
|
MOSAIC_HOME="${MOSAIC_HOME:-$HOME/.config/mosaic}"
|
||||||
SKILLS_REPO_URL="${MOSAIC_SKILLS_REPO_URL:-https://git.mosaicstack.dev/mosaic/agent-skills.git}"
|
|
||||||
SKILLS_REPO_DIR="${MOSAIC_SKILLS_REPO_DIR:-$MOSAIC_HOME/sources/agent-skills}"
|
|
||||||
MOSAIC_SKILLS_DIR="$MOSAIC_HOME/skills"
|
MOSAIC_SKILLS_DIR="$MOSAIC_HOME/skills"
|
||||||
MOSAIC_LOCAL_SKILLS_DIR="$MOSAIC_HOME/skills-local"
|
MOSAIC_LOCAL_SKILLS_DIR="$MOSAIC_HOME/skills-local"
|
||||||
|
|
||||||
@@ -12,24 +17,21 @@ MOSAIC_LOCAL_SKILLS_DIR="$MOSAIC_HOME/skills-local"
|
|||||||
# (the legacy "mosaic sync" full-catalog behavior).
|
# (the legacy "mosaic sync" full-catalog behavior).
|
||||||
MOSAIC_INSTALL_SKILLS="${MOSAIC_INSTALL_SKILLS:-}"
|
MOSAIC_INSTALL_SKILLS="${MOSAIC_INSTALL_SKILLS:-}"
|
||||||
|
|
||||||
fetch=1
|
|
||||||
link_only=0
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat <<USAGE
|
cat <<USAGE
|
||||||
Usage: $(basename "$0") [options]
|
Usage: $(basename "$0") [options]
|
||||||
|
|
||||||
Sync canonical skills into ~/.config/mosaic/skills and link all Mosaic skills into runtime skill directories.
|
Link installed skills from ~/.config/mosaic/{skills,skills-local} into runtime
|
||||||
|
skill directories. Canonical skills arrive with the framework installer; this
|
||||||
|
script never clones or pulls a second repository.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--link-only Skip git clone/pull and only relink from ~/.config/mosaic/{skills,skills-local}
|
--link-only Accepted for compatibility; linking is now the whole job
|
||||||
--no-link Sync canonical skills but do not update runtime links
|
--no-link Do nothing (kept for compatibility)
|
||||||
-h, --help Show help
|
-h, --help Show help
|
||||||
|
|
||||||
Env:
|
Env:
|
||||||
MOSAIC_HOME Default: ~/.config/mosaic
|
MOSAIC_HOME Default: ~/.config/mosaic
|
||||||
MOSAIC_SKILLS_REPO_URL Default: https://git.mosaicstack.dev/mosaic/agent-skills.git
|
|
||||||
MOSAIC_SKILLS_REPO_DIR Default: ~/.config/mosaic/sources/agent-skills
|
|
||||||
MOSAIC_INSTALL_SKILLS Colon-separated list of skills to link (default: all)
|
MOSAIC_INSTALL_SKILLS Colon-separated list of skills to link (default: all)
|
||||||
USAGE
|
USAGE
|
||||||
}
|
}
|
||||||
@@ -37,12 +39,12 @@ USAGE
|
|||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--link-only)
|
--link-only)
|
||||||
fetch=0
|
# Compat no-op: fetching a skills repo no longer exists.
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--no-link)
|
--no-link)
|
||||||
link_only=1
|
echo "[mosaic-skills] Nothing to do (--no-link; canonical skills ship with the installer)"
|
||||||
shift
|
exit 0
|
||||||
;;
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
usage
|
usage
|
||||||
@@ -58,101 +60,12 @@ done
|
|||||||
|
|
||||||
mkdir -p "$MOSAIC_HOME" "$MOSAIC_SKILLS_DIR" "$MOSAIC_LOCAL_SKILLS_DIR"
|
mkdir -p "$MOSAIC_HOME" "$MOSAIC_SKILLS_DIR" "$MOSAIC_LOCAL_SKILLS_DIR"
|
||||||
|
|
||||||
if [[ $fetch -eq 1 ]]; then
|
|
||||||
if [[ -d "$SKILLS_REPO_DIR/.git" ]]; then
|
|
||||||
echo "[mosaic-skills] Updating skills source: $SKILLS_REPO_DIR"
|
|
||||||
|
|
||||||
# ── Detect dirty state ──────────────────────────────────────────────
|
|
||||||
dirty=""
|
|
||||||
dirty="$(git -C "$SKILLS_REPO_DIR" status --porcelain 2>/dev/null || true)"
|
|
||||||
|
|
||||||
if [[ -n "$dirty" ]]; then
|
|
||||||
# ── Auto-migrate customized skills to skills-local/ ─────────────
|
|
||||||
# Instead of stash/pop (fragile, merge conflicts), we:
|
|
||||||
# 1. Identify which skill dirs contain user edits
|
|
||||||
# 2. Copy those full skill dirs into skills-local/ (preserving edits)
|
|
||||||
# 3. Reset the repo clean so pull always succeeds
|
|
||||||
# 4. skills-local/ takes precedence during linking, so edits win
|
|
||||||
|
|
||||||
SOURCE_SKILLS_SUBDIR="$SKILLS_REPO_DIR/skills"
|
|
||||||
migrated=()
|
|
||||||
|
|
||||||
while IFS= read -r line; do
|
|
||||||
# porcelain format: XY <path> — extract the file path
|
|
||||||
file="${line:3}"
|
|
||||||
# Only migrate files under skills/ subdir in the repo
|
|
||||||
if [[ "$file" == skills/* ]]; then
|
|
||||||
# Extract the skill directory name (first path component after skills/)
|
|
||||||
skill_name="${file#skills/}"
|
|
||||||
skill_name="${skill_name%%/*}"
|
|
||||||
|
|
||||||
# Skip if already migrated this skill in this run
|
|
||||||
local_skill_dir="$MOSAIC_LOCAL_SKILLS_DIR/$skill_name"
|
|
||||||
if [[ -d "$local_skill_dir" ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Skip if skill_name is empty or hidden
|
|
||||||
if [[ -z "$skill_name" || "$skill_name" == .* ]]; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy the skill (with user's edits) from repo working tree to skills-local/
|
|
||||||
if [[ -d "$SOURCE_SKILLS_SUBDIR/$skill_name" ]]; then
|
|
||||||
cp -R "$SOURCE_SKILLS_SUBDIR/$skill_name" "$local_skill_dir"
|
|
||||||
migrated+=("$skill_name")
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done <<< "$dirty"
|
|
||||||
|
|
||||||
if [[ ${#migrated[@]} -gt 0 ]]; then
|
|
||||||
echo "[mosaic-skills] Migrated ${#migrated[@]} customized skill(s) to skills-local/:"
|
|
||||||
for s in "${migrated[@]}"; do
|
|
||||||
echo " → $MOSAIC_LOCAL_SKILLS_DIR/$s"
|
|
||||||
done
|
|
||||||
echo "[mosaic-skills] Your edits are preserved there and take precedence over canonical."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Reset repo to clean state so pull always works
|
|
||||||
echo "[mosaic-skills] Resetting source repo to clean state..."
|
|
||||||
git -C "$SKILLS_REPO_DIR" checkout . 2>/dev/null || true
|
|
||||||
git -C "$SKILLS_REPO_DIR" clean -fd 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! git -C "$SKILLS_REPO_DIR" pull --rebase 2>/dev/null; then
|
|
||||||
echo "[mosaic-skills] WARN: pull failed — continuing with existing checkout" >&2
|
|
||||||
git -C "$SKILLS_REPO_DIR" rebase --abort 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "[mosaic-skills] Cloning skills source to: $SKILLS_REPO_DIR"
|
|
||||||
mkdir -p "$(dirname "$SKILLS_REPO_DIR")"
|
|
||||||
git clone "$SKILLS_REPO_URL" "$SKILLS_REPO_DIR"
|
|
||||||
fi
|
|
||||||
|
|
||||||
SOURCE_SKILLS_DIR="$SKILLS_REPO_DIR/skills"
|
|
||||||
if [[ ! -d "$SOURCE_SKILLS_DIR" ]]; then
|
|
||||||
echo "[mosaic-skills] Missing source skills dir: $SOURCE_SKILLS_DIR" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if command -v rsync >/dev/null 2>&1; then
|
|
||||||
rsync -a --delete "$SOURCE_SKILLS_DIR/" "$MOSAIC_SKILLS_DIR/"
|
|
||||||
else
|
|
||||||
rm -rf "$MOSAIC_SKILLS_DIR"/*
|
|
||||||
cp -R "$SOURCE_SKILLS_DIR"/* "$MOSAIC_SKILLS_DIR"/
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -d "$MOSAIC_SKILLS_DIR" ]]; then
|
if [[ ! -d "$MOSAIC_SKILLS_DIR" ]]; then
|
||||||
echo "[mosaic-skills] Canonical skills dir missing: $MOSAIC_SKILLS_DIR" >&2
|
echo "[mosaic-skills] Canonical skills dir missing: $MOSAIC_SKILLS_DIR" >&2
|
||||||
|
echo "[mosaic-skills] Canonical skills ship with the framework — reinstall or update the framework package" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $link_only -eq 1 ]]; then
|
|
||||||
echo "[mosaic-skills] Canonical sync completed (link update skipped)"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Skills are linked into the MOSAIC-OWNED harness homes, never a base install.
|
# Skills are linked into the MOSAIC-OWNED harness homes, never a base install.
|
||||||
# Paths mirror the config-dir env vars the launcher injects (HARNESS_HOME_ENV in
|
# Paths mirror the config-dir env vars the launcher injects (HARNESS_HOME_ENV in
|
||||||
# commands/launch.js):
|
# commands/launch.js):
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# mosaic-sync-skills.ps1
|
# mosaic-sync-skills.ps1
|
||||||
# Syncs canonical skills and links them into agent runtime skill directories.
|
# Links the INSTALLED canonical skills into agent runtime skill directories.
|
||||||
|
# Canonical skills ship inside the framework package and are installed into
|
||||||
|
# ~/.config/mosaic/skills by the framework installer — there is no second
|
||||||
|
# repository to clone. This script only maintains the runtime links.
|
||||||
# Uses directory junctions (no elevation required) with fallback to copies.
|
# Uses directory junctions (no elevation required) with fallback to copies.
|
||||||
# PowerShell equivalent of mosaic-sync-skills (bash).
|
# PowerShell equivalent of mosaic-sync-skills (bash).
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
@@ -11,8 +14,6 @@ param(
|
|||||||
)
|
)
|
||||||
|
|
||||||
$MosaicHome = if ($env:MOSAIC_HOME) { $env:MOSAIC_HOME } else { Join-Path $env:USERPROFILE ".config\mosaic" }
|
$MosaicHome = if ($env:MOSAIC_HOME) { $env:MOSAIC_HOME } else { Join-Path $env:USERPROFILE ".config\mosaic" }
|
||||||
$SkillsRepoUrl = if ($env:MOSAIC_SKILLS_REPO_URL) { $env:MOSAIC_SKILLS_REPO_URL } else { "https://git.mosaicstack.dev/mosaic/agent-skills.git" }
|
|
||||||
$SkillsRepoDir = if ($env:MOSAIC_SKILLS_REPO_DIR) { $env:MOSAIC_SKILLS_REPO_DIR } else { Join-Path $MosaicHome "sources\agent-skills" }
|
|
||||||
$MosaicSkillsDir = Join-Path $MosaicHome "skills"
|
$MosaicSkillsDir = Join-Path $MosaicHome "skills"
|
||||||
$MosaicLocalSkillsDir = Join-Path $MosaicHome "skills-local"
|
$MosaicLocalSkillsDir = Join-Path $MosaicHome "skills-local"
|
||||||
|
|
||||||
@@ -20,47 +21,27 @@ if ($Help) {
|
|||||||
Write-Host @"
|
Write-Host @"
|
||||||
Usage: mosaic-sync-skills.ps1 [-LinkOnly] [-NoLink] [-Help]
|
Usage: mosaic-sync-skills.ps1 [-LinkOnly] [-NoLink] [-Help]
|
||||||
|
|
||||||
Sync canonical skills into ~/.config/mosaic/skills and link all Mosaic skills
|
Link installed skills from ~/.config/mosaic/{skills,skills-local} into runtime
|
||||||
into runtime skill directories using directory junctions.
|
skill directories using directory junctions. Canonical skills arrive with the
|
||||||
|
framework installer; this script never clones or pulls a second repository.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-LinkOnly Skip git clone/pull and only relink
|
-LinkOnly Accepted for compatibility; linking is now the whole job
|
||||||
-NoLink Sync canonical skills but do not update runtime links
|
-NoLink Do nothing (kept for compatibility)
|
||||||
-Help Show help
|
-Help Show help
|
||||||
"@
|
"@
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($NoLink) {
|
||||||
|
Write-Host "[mosaic-skills] Nothing to do (-NoLink; canonical skills ship with the installer)"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($d in @($MosaicHome, $MosaicSkillsDir, $MosaicLocalSkillsDir)) {
|
foreach ($d in @($MosaicHome, $MosaicSkillsDir, $MosaicLocalSkillsDir)) {
|
||||||
if (-not (Test-Path $d)) { New-Item -ItemType Directory -Path $d -Force | Out-Null }
|
if (-not (Test-Path $d)) { New-Item -ItemType Directory -Path $d -Force | Out-Null }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fetch skills from git
|
|
||||||
if (-not $LinkOnly) {
|
|
||||||
if (Test-Path (Join-Path $SkillsRepoDir ".git")) {
|
|
||||||
Write-Host "[mosaic-skills] Updating skills source: $SkillsRepoDir"
|
|
||||||
git -C $SkillsRepoDir pull --rebase
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Host "[mosaic-skills] Cloning skills source to: $SkillsRepoDir"
|
|
||||||
$parentDir = Split-Path $SkillsRepoDir -Parent
|
|
||||||
if (-not (Test-Path $parentDir)) { New-Item -ItemType Directory -Path $parentDir -Force | Out-Null }
|
|
||||||
git clone $SkillsRepoUrl $SkillsRepoDir
|
|
||||||
}
|
|
||||||
|
|
||||||
$sourceSkillsDir = Join-Path $SkillsRepoDir "skills"
|
|
||||||
if (-not (Test-Path $sourceSkillsDir)) {
|
|
||||||
Write-Host "[mosaic-skills] Missing source skills dir: $sourceSkillsDir" -ForegroundColor Red
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sync: remove old, copy new
|
|
||||||
if (Test-Path $MosaicSkillsDir) {
|
|
||||||
Get-ChildItem $MosaicSkillsDir | Remove-Item -Recurse -Force
|
|
||||||
}
|
|
||||||
Copy-Item "$sourceSkillsDir\*" $MosaicSkillsDir -Recurse -Force
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not (Test-Path $MosaicSkillsDir)) {
|
if (-not (Test-Path $MosaicSkillsDir)) {
|
||||||
Write-Host "[mosaic-skills] Canonical skills dir missing: $MosaicSkillsDir" -ForegroundColor Red
|
Write-Host "[mosaic-skills] Canonical skills dir missing: $MosaicSkillsDir" -ForegroundColor Red
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -1450,7 +1450,7 @@ export function registerLaunchCommands(program: Command): void {
|
|||||||
// Direct framework script delegates
|
// Direct framework script delegates
|
||||||
const directCommands: Record<string, { desc: string; script: string }> = {
|
const directCommands: Record<string, { desc: string; script: string }> = {
|
||||||
init: { desc: 'Generate SOUL.md (agent identity contract)', script: 'mosaic-init' },
|
init: { desc: 'Generate SOUL.md (agent identity contract)', script: 'mosaic-init' },
|
||||||
sync: { desc: 'Sync skills from canonical source', script: 'mosaic-sync-skills' },
|
sync: { desc: 'Link installed skills into runtime homes', script: 'mosaic-sync-skills' },
|
||||||
bootstrap: {
|
bootstrap: {
|
||||||
desc: 'Bootstrap a repo with Mosaic standards',
|
desc: 'Bootstrap a repo with Mosaic standards',
|
||||||
script: 'mosaic-bootstrap-repo',
|
script: 'mosaic-bootstrap-repo',
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ export function syncDirectory(
|
|||||||
const relPath = relative(relBase, src);
|
const relPath = relative(relBase, src);
|
||||||
const dirName = relPath.split('/').pop() ?? '';
|
const dirName = relPath.split('/').pop() ?? '';
|
||||||
|
|
||||||
// Skip any .git directory (top-level or nested, e.g. sources/agent-skills/.git)
|
// Skip any .git directory (top-level or nested; defensive — the
|
||||||
|
// framework tree itself is not a git checkout at install time)
|
||||||
if (options.excludeGit && (dirName === '.git' || relPath.includes('/.git'))) return;
|
if (options.excludeGit && (dirName === '.git' || relPath.includes('/.git'))) return;
|
||||||
|
|
||||||
// Skip preserved paths at top level
|
// Skip preserved paths at top level
|
||||||
|
|||||||
@@ -20,12 +20,6 @@ export function loadSkillsCatalog(mosaicHome: string): SkillEntry[] {
|
|||||||
skills.push(...loadSkillsFromDir(canonicalDir, 'canonical'));
|
skills.push(...loadSkillsFromDir(canonicalDir, 'canonical'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to source repo
|
|
||||||
const sourceDir = join(mosaicHome, 'sources', 'agent-skills', 'skills');
|
|
||||||
if (skills.length === 0 && existsSync(sourceDir)) {
|
|
||||||
skills.push(...loadSkillsFromDir(sourceDir, 'canonical'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load local skills
|
// Load local skills
|
||||||
const localDir = join(mosaicHome, 'skills-local');
|
const localDir = join(mosaicHome, 'skills-local');
|
||||||
if (existsSync(localDir)) {
|
if (existsSync(localDir)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user