Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .codex/INSTALL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Installing obsidian-skills for Codex

This guide explains how to install obsidian-skills using Codex native skill discovery.

## Quick Install (One-line)

Run this from anywhere — no need to clone the repo first:

macOS / Linux:

```bash
tmp_dir="$(mktemp -d)" && git clone --depth 1 https://github.com/kepano/obsidian-skills.git "$tmp_dir/obsidian-skills" && "$tmp_dir/obsidian-skills/scripts/install-skills-codex.sh" && rm -rf "$tmp_dir"
```

Windows (PowerShell):

```powershell
$tmp_dir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid()); New-Item -ItemType Directory -Path $tmp_dir | Out-Null; git clone --depth 1 https://github.com/kepano/obsidian-skills.git "$tmp_dir\obsidian-skills"; & "$tmp_dir\obsidian-skills\scripts\install-skills-codex.ps1"; Remove-Item -Recurse -Force $tmp_dir
```

## Install from Repo Root

If you have already cloned the repo:

macOS / Linux:

```bash
./scripts/install-skills-codex.sh
```

Windows (PowerShell):

```powershell
.\scripts\install-skills-codex.ps1
```

## What This Does

- Syncs all skills from `skills/` into `~/.agents/skills/obsidian-skills/`
- Skills are discovered automatically by Codex at next startup

## Verify

macOS / Linux:

```bash
ls -la ~/.agents/skills/obsidian-skills
```

Windows (PowerShell):

```powershell
Get-ChildItem "$HOME\.agents\skills\obsidian-skills"
```

Expected directories (one per skill):

- `defuddle`
- `json-canvas`
- `obsidian-bases`
- `obsidian-cli`
- `obsidian-markdown`

## Options

macOS / Linux:

```bash
# Preview without writing
./scripts/install-skills-codex.sh --dry-run

# Custom skills directory
./scripts/install-skills-codex.sh --skills-dir /custom/path/skills/obsidian-skills
```

Windows (PowerShell):

```powershell
# Preview without writing
.\scripts\install-skills-codex.ps1 -DryRun

# Custom skills directory
.\scripts\install-skills-codex.ps1 -SkillsDir C:\custom\path\skills\obsidian-skills
```

## Update

Re-run the install script to sync the latest skills:

macOS / Linux:

```bash
./scripts/install-skills-codex.sh
```

Windows (PowerShell):

```powershell
.\scripts\install-skills-codex.ps1
```

Or use the one-line command above to fetch and install the latest version.

## Uninstall

macOS / Linux:

```bash
rm -rf ~/.agents/skills/obsidian-skills
```

Windows (PowerShell):

```powershell
Remove-Item -Recurse -Force "$HOME\.agents\skills\obsidian-skills"
```
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,41 @@ Add the contents of this repo to a `/.claude` folder in the root of your Obsidia

#### Codex CLI

Copy the `skills/` directory into your Codex skills path (typically `~/.codex/skills`). See the [Agent Skills specification](https://agentskills.io/specification) for the standard skill format.
**Option 1 — Tell Codex to install (recommended):**

```
Fetch and follow instructions from https://raw.githubusercontent.com/kepano/obsidian-skills/main/.codex/INSTALL.md
```

**Option 2 — One-line script install:**

macOS / Linux:

```bash
tmp_dir="$(mktemp -d)" && git clone --depth 1 https://github.com/kepano/obsidian-skills.git "$tmp_dir/obsidian-skills" && "$tmp_dir/obsidian-skills/scripts/install-skills-codex.sh" && rm -rf "$tmp_dir"
```

Windows (PowerShell):

```powershell
$tmp_dir = Join-Path ([System.IO.Path]::GetTempPath()) ([System.Guid]::NewGuid()); New-Item -ItemType Directory -Path $tmp_dir | Out-Null; git clone --depth 1 https://github.com/kepano/obsidian-skills.git "$tmp_dir\obsidian-skills"; & "$tmp_dir\obsidian-skills\scripts\install-skills-codex.ps1"; Remove-Item -Recurse -Force $tmp_dir
```

**Option 3 — From the repo root:**

macOS / Linux:

```bash
./scripts/install-skills-codex.sh
```

Windows (PowerShell):

```powershell
.\scripts\install-skills-codex.ps1
```

This installs all skills into `~/.agents/skills/obsidian-skills/`. Restart Codex to discover them. See [`.codex/INSTALL.md`](.codex/INSTALL.md) for options including `--dry-run` and custom target directories.

#### OpenCode

Expand Down
101 changes: 101 additions & 0 deletions scripts/install-skills-codex.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#Requires -Version 5.1
<#
.SYNOPSIS
Install obsidian-skills for Codex native skill discovery.

.DESCRIPTION
Syncs each skill from skills/ into the Codex skills directory
(default: ~/.agents/skills/obsidian-skills).

.PARAMETER SkillsDir
Target skills directory (default: ~/.agents/skills/obsidian-skills)

.PARAMETER DryRun
Print actions without writing anything

.EXAMPLE
.\scripts\install-skills-codex.ps1

.EXAMPLE
.\scripts\install-skills-codex.ps1 -SkillsDir C:\custom\path\skills\obsidian-skills

.EXAMPLE
.\scripts\install-skills-codex.ps1 -DryRun
#>

param(
[string]$SkillsDir = (Join-Path $HOME '.agents' 'skills' 'obsidian-skills'),
[switch]$DryRun
)

$ErrorActionPreference = 'Stop'

$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$RepoRoot = Split-Path -Parent $ScriptDir

function Write-Log {
param([string]$Message)
Write-Host "[install-skills] $Message"
}

function Invoke-Die {
param([string]$Message)
Write-Error "[install-skills] Error: $Message"
exit 1
}

# Validate repo structure
$SkillsSrc = Join-Path $RepoRoot "skills"
if (-not (Test-Path -Path $SkillsSrc -PathType Container)) {
Invoke-Die "skills/ directory not found under repo root: $RepoRoot"
}

# Collect skill names
$SkillNames = Get-ChildItem -Path $SkillsSrc -Directory |
Sort-Object Name |
Select-Object -ExpandProperty Name

if ($SkillNames.Count -eq 0) {
Invoke-Die "No skills found in $SkillsSrc"
}

function Sync-Skill {
param([string]$SkillName)

$src = Join-Path $SkillsSrc $SkillName
$dst = Join-Path $SkillsDir $SkillName

if ($DryRun) {
Write-Log "DRY-RUN: sync $src -> $dst"
return
}

# Ensure destination parent exists
if (-not (Test-Path -Path $dst)) {
New-Item -ItemType Directory -Path $dst -Force | Out-Null
}

# Copy all items from src to dst, overwriting existing files
Copy-Item -Path (Join-Path $src '*') -Destination $dst -Recurse -Force

# Remove items in dst that are no longer in src
Get-ChildItem -Path $dst | Where-Object {
-not (Test-Path (Join-Path $src $_.Name))
} | Remove-Item -Recurse -Force
}

if ($DryRun) {
Write-Log "DRY-RUN mode — no files will be written"
}

Write-Log "Installing obsidian-skills to: $SkillsDir"

foreach ($skill in $SkillNames) {
Write-Log "Syncing skill: $skill"
Sync-Skill -SkillName $skill
}

if (-not $DryRun) {
Write-Log "Done. Skills installed to: $SkillsDir"
Write-Log "Restart Codex to discover the new skills."
}
116 changes: 116 additions & 0 deletions scripts/install-skills-codex.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env bash
#
# Install obsidian-skills for Codex native skill discovery.
#
# Syncs each skill from skills/ into the Codex skills directory
# (default: ~/.agents/skills/obsidian-skills).
#
# Usage:
# ./scripts/install-skills-codex.sh [options]
#
# Options:
# --skills-dir PATH Target skills directory (default: ~/.agents/skills/obsidian-skills)
# --dry-run Print actions without writing anything
# -h, --help Show this help message
#

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SKILLS_DIR="${HOME}/.agents/skills/obsidian-skills"
DRY_RUN="false"

usage() {
cat <<EOF
Install obsidian-skills for Codex native skill discovery.

Usage:
scripts/install-skills-codex.sh [options]

Options:
--skills-dir PATH Target skills directory (default: ~/.agents/skills/obsidian-skills)
--dry-run Print actions without writing anything
-h, --help Show this help message
EOF
}

log() {
printf '[install-skills] %s\n' "$*"
}

die() {
printf '[install-skills] Error: %s\n' "$*" >&2
exit 1
}

# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--skills-dir)
SKILLS_DIR="$2"
shift 2
;;
--dry-run)
DRY_RUN="true"
shift
;;
-h|--help)
usage
exit 0
;;
*)
die "Unknown option: $1"
;;
esac
done

# Validate repo structure
[[ -d "$REPO_ROOT/skills" ]] || die "skills/ directory not found under repo root: $REPO_ROOT"

# Collect skill names
mapfile -t SKILL_NAMES < <(find "$REPO_ROOT/skills" -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | sort)
[[ ${#SKILL_NAMES[@]} -gt 0 ]] || die "No skills found in $REPO_ROOT/skills"

sync_skill() {
local skill="$1"
local src="$REPO_ROOT/skills/$skill"
local dst="$SKILLS_DIR/$skill"

if [[ "$DRY_RUN" == "true" ]]; then
log "DRY-RUN: sync $src -> $dst"
return
fi

mkdir -p "$dst"
if command -v rsync >/dev/null 2>&1; then
rsync -a --delete "$src/" "$dst/"
else
local tmp_dst
mkdir -p "$(dirname "$dst")"
tmp_dst="$(mktemp -d)"
if cp -a "$src/." "$tmp_dst/"; then
rm -rf "$dst"
mv "$tmp_dst" "$dst"
else
rm -rf "$tmp_dst"
die "Failed to copy $src to $dst"
fi
fi
}

if [[ "$DRY_RUN" == "true" ]]; then
log "DRY-RUN mode — no files will be written"
fi

log "Installing obsidian-skills to: $SKILLS_DIR"

for skill in "${SKILL_NAMES[@]}"; do
log "Syncing skill: $skill"
sync_skill "$skill"
done

if [[ "$DRY_RUN" == "false" ]]; then
log "Done. Skills installed to: $SKILLS_DIR"
log "Restart Codex to discover the new skills."
fi