Skip to content
Merged
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
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,13 @@ Then `chezmoi apply`.
- Containers: macOS Apple silicon [`container`](https://github.com/apple/container) + third-party [`container-compose`](https://github.com/Mcrich23/Container-Compose); Linux [`podman`](https://podman.io).
- Docs: [`hugo`](https://gohugo.io), [`typst`](https://typst.app), [`tldr`](https://tldr.sh).
- OpenCode zh-TW linting: [`zhtw-mcp`](https://github.com/sysprog21/zhtw-mcp) is configured as a local MCP server at `~/.local/bin/zhtw-mcp`. Until upstream publishes releases, install it from source with `make install` so OpenCode can use the fixed binary path.
- OpenCode Loop: [`@bybrawe/opencode-loop@0.5.1`](https://github.com/ByBrawe/opencode-loop) is loaded through OpenCode's native npm plugin support, with `/loop*` command stubs managed under `~/.config/opencode/commands/`.
- OpenCode Claude Code plugin: [`@khalilgharbaoui/opencode-claude-code-plugin@0.6.2`](https://github.com/khalilgharbaoui/opencode-claude-code-plugin) is loaded through OpenCode's native npm plugin support; after changing the plugin path, run `chezmoi apply /home/collie/.config/opencode/opencode.json` and restart OpenCode.
- OpenCode Claude Code plugin: [`@khalilgharbaoui/opencode-claude-code-plugin`](https://github.com/khalilgharbaoui/opencode-claude-code-plugin) is loaded through OpenCode's native npm plugin support; after changing the plugin list, run `chezmoi apply /home/collie/.config/opencode/opencode.json` and restart OpenCode.

### AI extensions

- [`home/.chezmoidata/ai.yaml`](home/.chezmoidata/ai.yaml) is the single inventory for user skills, marketplaces, and plugins across Claude Code, Codex, and OpenCode. Entries intentionally track upstream latest releases.
- `run_after_5-sync-ai-extensions.sh.tmpl` synchronizes Claude Code and Codex plugins and copies listed skills to each CLI's user skill directory on every `chezmoi apply`. Removing an entry from the inventory does not uninstall existing local content.
- OpenCode plugins are rendered into `~/.config/opencode/opencode.json`; OpenCode installs them at startup. Review and trust new Codex hooks manually with `/hooks`.

### Fish plugins (managed by [`fisher`](https://github.com/jorgebucaran/fisher))

Expand Down
30 changes: 30 additions & 0 deletions home/.chezmoidata/ai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
ai:
skills:
- id: addyosmani-agent-skills
type: git
source: https://github.com/addyosmani/agent-skills.git
path: skills
hosts: [claude, codex, opencode]
- id: respond-structured
type: local
path: .local/share/ai-skills
hosts: [claude, codex, opencode]

claude:
marketplaces:
- name: ponytail
source: DietrichGebert/ponytail
plugins:
- ponytail@ponytail

codex:
marketplaces:
- name: ponytail
source: DietrichGebert/ponytail
plugins:
- ponytail@ponytail

opencode:
plugins:
- "@khalilgharbaoui/opencode-claude-code-plugin"
- "@dietrichgebert/ponytail"
12 changes: 0 additions & 12 deletions home/.chezmoiexternal.toml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,3 @@ refreshPeriod = "168h"
type = "file"
url = "https://raw.githubusercontent.com/catppuccin/alacritty/main/catppuccin-mocha.toml"
refreshPeriod = "168h"

[".config/opencode/skills"]
type = "archive"
url = "https://github.com/addyosmani/agent-skills/archive/refs/heads/main.tar.gz"
stripComponents = 2
include = ["*/skills/**"]
refreshPeriod = "168h"

[".config/opencode/skills/LICENSE.addyosmani-agent-skills"]
type = "file"
url = "https://raw.githubusercontent.com/addyosmani/agent-skills/main/LICENSE"
refreshPeriod = "168h"
102 changes: 102 additions & 0 deletions home/.chezmoiscripts/run_after_5-sync-ai-extensions.sh.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env bash
set -euo pipefail

info() {
printf 'AI extensions: %s\n' "$*"
}

skill_destination() {
case "$1" in
claude) printf '%s\n' "$HOME/.claude/skills" ;;
codex) printf '%s\n' "$HOME/.agents/skills" ;;
opencode) printf '%s\n' "$HOME/.config/opencode/skills" ;;
*)
printf 'Unknown AI skill host: %s\n' "$1" >&2
return 1
;;
esac
}

sync_skill_collection() {
local source="$1"
local path="$2"
shift 2

if [[ ! -d "$source/$path" ]]; then
printf 'AI skill source is missing: %s\n' "$source/$path" >&2
return 1
fi

local host destination skill
for host in "$@"; do
destination="$(skill_destination "$host")"
mkdir -p "$destination"
for skill in "$source/$path"/*; do
[[ -d "$skill" ]] || continue
cp -a "$skill" "$destination/"
done
done
}

sync_git_skill_collection() {
local id="$1"
local source="$2"
local path="$3"
shift 3
local checkout="$HOME/.local/share/chezmoi-ai/sources/$id"

mkdir -p "$(dirname "$checkout")"
if [[ ! -d "$checkout/.git" ]]; then
info "Cloning skill collection $id"
git clone --depth=1 "$source" "$checkout"
elif git -C "$checkout" diff --quiet && git -C "$checkout" diff --cached --quiet; then
info "Updating skill collection $id"
git -C "$checkout" pull --ff-only
else
info "Keeping locally modified skill collection $id"
fi

sync_skill_collection "$checkout" "$path" "$@"
}

if command -v claude >/dev/null 2>&1; then
info "Synchronizing Claude Code plugins"
{{- range .ai.claude.marketplaces }}
if ! claude plugin marketplace list --json | grep -Fq '"name": "{{ .name }}"'; then
claude plugin marketplace add "{{ .source }}" --scope user
fi
claude plugin marketplace update "{{ .name }}"
{{- end }}
{{- range .ai.claude.plugins }}
if claude plugin list --json | grep -Fq '"id": "{{ . }}"'; then
claude plugin update "{{ . }}" --scope user
else
claude plugin install "{{ . }}" --scope user
fi
{{- end }}
else
info "Claude Code is not installed; skipping"
fi

if command -v codex >/dev/null 2>&1; then
info "Synchronizing Codex plugins"
{{- range .ai.codex.marketplaces }}
if ! codex plugin marketplace list --json | grep -Fq '"name": "{{ .name }}"'; then
codex plugin marketplace add "{{ .source }}" --json
fi
codex plugin marketplace upgrade "{{ .name }}" --json
{{- end }}
{{- range .ai.codex.plugins }}
codex plugin add "{{ . }}" --json
{{- end }}
else
info "Codex is not installed; skipping"
fi

{{- range .ai.skills }}
{{- if eq .type "git" }}
sync_git_skill_collection "{{ .id }}" "{{ .source }}" "{{ .path }}"{{ range .hosts }} "{{ . }}"{{ end }}
{{- else if eq .type "local" }}
sync_skill_collection "$HOME/{{ .path }}" "."{{ range .hosts }} "{{ . }}"{{ end }}
{{- end }}
{{- end }}
22 changes: 0 additions & 22 deletions home/dot_claude/private_settings.json

This file was deleted.

36 changes: 36 additions & 0 deletions home/dot_claude/private_settings.json.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"permissions": {
"allow": [
"mcp__opencode_proxy__bash",
"mcp__opencode_proxy__edit",
"mcp__opencode_proxy__write",
"mcp__opencode_proxy__webfetch",
"mcp__opencode_proxy__task",
"mcp__context7",
"mcp__zhtw-mcp__zhtw",
"WebSearch"
]
},
"model": "opus",
"effortLevel": "max",
"enabledPlugins": {
{{- range $index, $plugin := .ai.claude.plugins }}
{{- if $index }},{{ end }}
"{{ $plugin }}": true
{{- end }}
},
"extraKnownMarketplaces": {
{{- range $index, $marketplace := .ai.claude.marketplaces }}
{{- if $index }},{{ end }}
"{{ $marketplace.name }}": {
"source": {
"source": "github",
"repo": "{{ $marketplace.source }}"
}
}
{{- end }}
},
"theme": "dark",
"verbose": true,
"skipAutoPermissionPrompt": true
}
5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-clear.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-compact.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-dev.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-doctor.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-export.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-help.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-init.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-logs.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-now.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-pause.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-progress.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-remove.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-resume.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-safe-dev.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-status.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-stop.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop-testfix.md

This file was deleted.

5 changes: 0 additions & 5 deletions home/dot_config/opencode/commands/loop.md

This file was deleted.

6 changes: 4 additions & 2 deletions home/dot_config/opencode/opencode.json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
"$schema": "https://opencode.ai/config.json",
"shell": "fish",
"plugin": [
"@bybrawe/opencode-loop@0.5.1",
"@khalilgharbaoui/opencode-claude-code-plugin@latest"
{{- range $index, $plugin := .ai.opencode.plugins }}
{{- if $index }},{{ end }}
"{{ $plugin }}"
{{- end }}
],
"permission": {
"bash": "allow",
Expand Down
Loading