Repository navigation
fix(init): install Claude skills as loadable SKILL.md folders - #36
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Comment |
Claude Code only loads skills from .claude/skills/<name>/SKILL.md with name/description frontmatter, so the flat meta-*.md files that `meta init claude` wrote were never loaded. Install each skill as its own folder and delete the old flat file it replaces. Fix the skill text against the CLI: `meta git worktree` (not `meta worktree`), `remove`, no `--ordered`, `meta project sync` or `meta git setup-ssh`, `meta git update` only clones, parallel is the default. The worktree skill now says every change gets a worktree. `meta init claude --help` ran the install (and registered the plugin marketplace in the user's Claude settings); it now only prints help. Implements [[tasks/harmony-2708]]
Windows checks the skill files out with CRLF line endings. Implements [[tasks/harmony-2708]]
…ew findings Plain `meta init claude` skips existing files, so it now leaves old flat skill files alone too. Skill text: the root is only kept for --tag, worktree create needs --repo, meta-rust has no ordering, --primary still reads config from the cwd. Implements [[tasks/harmony-2708]]
--from-pr never applies to the root repo (add a root-PR recipe), drop the Actions example that relied on it, diff --stat is a no-op, run worktree commands from the primary checkout, context detection skips nested repos, include/exclude match the absolute path, snapshot restore asks without --force, --silent hides errors, clone --depth is shallow depth. Implements [[tasks/harmony-2708]]
…ew findings Close the worktree exec code fence. Snapshot restore resets branches, meta exec still offers commands to plugins, quote commands with shell syntax. Implements [[tasks/harmony-2708]]
Implements [[tasks/harmony-2708]]
Implements [[tasks/harmony-2708]]
prune treats a set holding only the root repo as orphaned and force-removes it. Also: remove skips nested repos' dirty check, cargo examples fail with meta-rust. Implements [[tasks/harmony-2708]]
…l fixes Implements [[tasks/harmony-2708]]
gold-silver-copper
force-pushed
the
harmony-2708
branch
from
October 24, 2026 00:37
0f3c3b3 to
61d360f
Compare
gold-silver-copper
added a commit
that referenced
this pull request
Oct 24, 2026
- A real .claude/skills/<name>/ folder holding only SKILL.md is meta's only when that SKILL.md is the shipped text (no release shipped the #36 layout, and its text is today's), so another tool's same-named skill is kept even with --force. - Rule files are not written through a symlinked .claude/, .claude/rules/ or rule file; they are reported as skipped. Implements [[tasks/harmony-2714]]
gold-silver-copper
added a commit
that referenced
this pull request
Oct 24, 2026
… folders (#38) feat(init): install skills into .meta/skills and link them into agent… … folders meta init claude now writes each skill to .meta/skills/<name>/SKILL.md and links it into .claude/skills/ and .agents/skills/ (Codex and other agents), as atc and git-kb do with .atc/skills/ and .kb/skills/. Other agent folders from atc's registry (.cursor, .opencode, .pi, .omp, .grok) get links when the agent's folder exists. --update turns both older layouts into links: flat .claude/skills/*.md files and real .claude/skills/<name>/ folders holding only SKILL.md. Anything else at a link path (another tool's link, a folder with more files, a file) is reported and left alone; no symlink is followed or removed. Where a symlink can't be made (Windows without Developer Mode), the skill folder is copied with a .meta-skill-copy marker, and a later --update replaces it with a link. A repo whose config is the legacy .meta file can't have the .meta/ folder: init refuses before writing anything and suggests git mv .meta .meta.json. The meta-repo check now uses find_meta_config_in, so a .meta/ folder is not taken for config. install_skills takes the tool name, skill bundle and agent folder list as inputs so it can move into a shared crate later. Implements [[tasks/harmony-2714]] fix(init): never write through symlinks; own legacy folders only in .… …claude Review fixes: - A symlink anywhere in .meta/skills/<name>/SKILL.md stops the install, and an agent skills folder reached through a symlink is skipped, so no other tool's files are written or removed through a link. - A real folder holding only SKILL.md counts as meta's only in .claude/skills/, where older releases wrote it. - A plain file holding exactly meta's link target (git's checkout of a link with core.symlinks=false) is replaced, so --update repairs such Windows clones. - The copy fallback copies .meta/skills/<name>/SKILL.md, not the embedded text, so a kept or newer committed skill is what agents see. Implements [[tasks/harmony-2714]] fix(init): own old skill folders only by their shipped text; guard rules - A real .claude/skills/<name>/ folder holding only SKILL.md is meta's only when that SKILL.md is the shipped text (no release shipped the #36 layout, and its text is today's), so another tool's same-named skill is kept even with --force. - Rule files are not written through a symlinked .claude/, .claude/rules/ or rule file; they are reported as skipped. Implements [[tasks/harmony-2714]] fix(init): never write settings.json through a symlink Implements [[tasks/harmony-2714]] fix(init): remove old flat skill files only when meta shipped them --update and --force removed any regular .claude/skills/meta-<name>.md. Now only files whose first line is the heading of a skill meta shipped (every release's flat files start with one of seven known headings) are removed; anything else is reported and kept. Also create .claude/rules/ after the skills step, so a refused install leaves no half-made .claude/. Implements [[tasks/harmony-2714]]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
meta init claudewrote each skill as a flat.claude/skills/meta-*.mdfile. Claude Code only loads skills from.claude/skills/<name>/SKILL.mdwithname/descriptionfrontmatter, so none of the six meta skills were ever loaded (in harmony, Claude's skill list has nometa-*entries). The worktree skill also used a command that doesn't exist (meta worktree) and told agents to skip worktrees for quick fixes.What changes
Install layout (
src/init.rs).claude/skills/meta-<name>/SKILL.mdwith frontmatter (descriptions from gitkb/meta'sclaude-plugin/skills). They are embedded with a smallskill!macro and installed at the same path.--updateor--force, the old flatmeta-<name>.mdeach folder replaces is deleted, so re-running in an existing repo leaves one copy. Plainmeta init claudeskips existing files, so it leaves them alone. Only those six filenames are touched; other files in.claude/skills/stay.Before / after in a repo:
meta init claude --help(src/main.rs) ran the full install, including registering thegitkb/claude-pluginsmarketplace in the user's global Claude settings. It now only prints the init help.Skill text, checked against
meta … --helpand the source of meta_cli, meta_git_cli, meta_git_lib, meta_project_cli and loop_lib:meta-worktree: rewritten.meta git worktree …everywhere,remove(notdestroy), positional commit-ish (not--from-ref),--no-deps/--recursive/--dry-run/--strict,list [<name>] --metadata-only. "Skip worktrees for quick single-file fixes" is replaced by: every change gets a worktree; read-only work may stay in the primary checkout. Also corrected:--ttl(not--ephemeral) is whatpruneacts on,removerefuses dirty repos without--force,post-destroyhook runs onremove.--from-prnever applies to the root repo and only warns when nothing matches, so the old GitHub Actions example could pass on unchanged code: it is removed, and the skill gives a root-PR recipe instead (git fetch origin <b>:<b>, thencreate <name> --repo .:<b> --repo <child> --strict; tried in a scratch repo with and without an existing local branch, andprune --dry-runleaves it alone: a set holding only the root repo is "orphaned" toprune, which force-removes it).diff --statis a no-op (diff always prints a stat summary of committed changes). Worktree commands must run from the primary checkout; context detection andworktree execskip repos nested inside another repo of the set;--include/--excludematch the absolute path, which contains the set name.meta-safety:meta --strict git worktree …;--strictcovers worktree checks only and doesn't roll back; removed--ordered(no such flag; dependency order comes from the MCP toolmeta_execution_order).meta-exec: with meta-rust installed everymeta exec -- cargo …goes to it (only build/test work); parallel is the default (--sequentialexists);--silenthides errors too; include/exclude are substring matches on paths;meta --exclude X exec -- cargo update(the old example passed--excludeto cargo);meta --primary exec; removed--ordered.meta-git:meta git updateonly clones missing repos (pull withmeta git pull);commitcommits staged changes; snapshot restore stashes tracked changes only and asks to confirm without--force; removedmeta git setup-ssh(it's a pass-through to a git command that doesn't exist).meta-plugins: nometa project sync(usemeta git update); plugin discovery is.meta/plugins/and~/.meta/plugins/; Rust plugin only if installed.meta-workspace:meta project list --recursive --json, "every repo at this level" instead of "ALL repos",meta git clone --depthis shallow depth (--meta-depthlimits recursion).Verification
cargo fmt --check,cargo clippy --all-targets -D warnings, and theinit::unit tests (10, incl. newtest_update_replaces_flat_skill_filesandtest_default_install_keeps_flat_skill_files) pass locally.PATHwithoutclaude:meta init claude --help→ prints help, creates nothing.meta init claude→ six.claude/skills/meta-*/SKILL.md+ rules + settings.meta init claude --updateover the six flat files plus acustom.md→ only folders remain,custom.mdkept.claude -p(no tools) asked to list skills starting withmeta-: lists all six in both scratch repos; in a repo with the old flat files:NONE.Notes
meta git update --helpsays it pulls existing repos but only clones missing ones;--from-prignores the root repo; context detection skips nested set members;diff --statis accepted but unused;prunetreats a root-only set as orphaned. The skills describe current behavior. The two installed rule files (.claude/rules/meta-*.md) also have small inaccuracies (meta git snapshot restorewithout--forceprompts;meta git commitcommits staged changes, not "all dirty repos";--includeis a substring match); left for a follow-up so the rules and their gitkb/meta copies change together.tests/init.bats; same branch name, so its CI builds this branch) and gitkb/harmony#154 (worktree policy in AGENTS.md). Harmony needs a meta release with this change, thenmeta init claude --update.Task: tasks/harmony-2708