Skip to content

Commit ad6cb75

Browse files
TPAteeqclaude
authored andcommitted
feat(install): add cross-framework agents platform (+ skills alias)
`graphify install --platform agents` installs the skill to the generic Agent-Skills locations: the spec's user-global ~/.agents/skills (global) and ./.agents/skills (--project) — the directories `npx skills` and spec-compliant frameworks read. `--platform skills` is an alias. Previously that user-global location was only reachable as an accidental side effect of the gemini-on-Windows branch. Bare `graphify install` is unchanged (still single-platform claude/windows). The platform is registered in tools/skillgen/platforms.toml (split, mirroring amp's agents-md body) and rendered through the skillgen drift/coverage guards. Since it is a post-v8 platform with no own v8 body, its --audit-coverage baseline is amp's v8 body (the body it re-homes). The rendered skill body is byte-identical to amp's; only the on-demand hooks reference differs (its own `graphify agents install` wording). The `graphify agents install` / `graphify skills install` subcommand is the amp-twin: it also wires an AGENTS.md always-on section, keeping it honest with the hooks reference it points at. The `--platform agents` path stays skill-only, exactly as amp's `--platform amp` does. Also: `skill-agents.md` added to package-data, and the wheel-packaging guard now covers every platform's skill body (not just references/always-on), so a missing skill body fails CI instead of only breaking install for real users. Closes #1405. Implements #1432. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 29fd98f commit ad6cb75

27 files changed

Lines changed: 3446 additions & 6 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Full release notes with details on each version: [GitHub Releases](https://githu
44

55
## Unreleased
66

7+
- Feat: new first-class `agents` platform installs the skill to the generic cross-framework Agent-Skills locations. `graphify install --platform agents` (alias `--platform skills`) writes the spec's user-global `~/.agents/skills/graphify/SKILL.md` — the directory `npx skills` and spec-compliant frameworks read — and `--project` writes `./.agents/skills/graphify/SKILL.md`; `graphify uninstall` removes them. Previously that user-global location was only reachable as an accidental side effect of the gemini-on-Windows branch. The skill bundle re-homes amp's agents-md body (registered in `tools/skillgen/platforms.toml`, rendered through the skillgen drift/coverage guards); the body is identical to amp's, and only the on-demand hooks reference differs — it points at `graphify agents install`, which (as the amp-twin subcommand) wires the skill plus an AGENTS.md always-on section. Bare `graphify install` is unchanged — still single-platform (claude/windows) (#1432, closes #1405).
8+
79
## 0.8.46 (2026-06-23)
810

911
- Perf: graph queries on large graphs are faster via a trigram candidate prefilter in the MCP/CLI query path. A trigram→node index (built once per graph and rebuilt on hot-reload) narrows the candidate set before the IDF-weighted scorer runs, cutting the previous O(N) scan. The prefilter is a strict superset of the exhaustive scorer (it indexes `norm_label`, `label_tokens`, `nid`, and `source_file`), so results and ranking are unchanged; short/CJK queries and low-selectivity terms fall back to the full scan (#1431; thanks @papinto).

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ for example `graphify claude install --project` or `graphify codex install --pro
142142
| Hermes | `graphify install --platform hermes` |
143143
| Kimi Code | `graphify install --platform kimi` |
144144
| Amp | `graphify amp install` |
145+
| Agent Skills (cross-framework) | `graphify install --platform agents` (alias `--platform skills`) |
145146
| Kiro IDE/CLI | `graphify kiro install` |
146147
| Pi coding agent | `graphify install --platform pi` |
147148
| Cursor | `graphify cursor install` |
@@ -150,6 +151,8 @@ for example `graphify claude install --project` or `graphify codex install --pro
150151

151152
Codex users also need `multi_agent = true` under `[features]` in `~/.codex/config.toml` for parallel extraction. CodeBuddy uses the same Agent tool and PreToolUse hook mechanism as Claude Code. Factory Droid uses the `Task` tool for parallel subagent dispatch. OpenClaw and Aider use sequential extraction (parallel agent support is still early on those platforms). Trae uses the Agent tool for parallel subagent dispatch and does **not** support PreToolUse hooks — AGENTS.md is the always-on mechanism.
152153

154+
`--platform agents` (alias `--platform skills`) targets the generic cross-framework [Agent-Skills](https://github.com/anthropics/skills) locations: the spec's user-global `~/.agents/skills/` (read by `npx skills` and spec-compliant frameworks) for a global install, and `./.agents/skills/` for a project (`--project`) install. The bare `graphify install` stays single-platform (Claude Code) by design — use the named `agents` platform when you want the skill discoverable by any framework that reads `.agents/skills`.
155+
153156
> Codex uses `$graphify` instead of `/graphify`.
154157
155158
### Optional extras
@@ -205,6 +208,7 @@ Run this once in your project after building a graph:
205208
| Hermes | `graphify hermes install` |
206209
| Kimi Code | `graphify install --platform kimi` |
207210
| Amp | `graphify amp install` |
211+
| Agent Skills (cross-framework) | `graphify agents install` (alias `graphify skills install`) |
208212
| Kiro IDE/CLI | `graphify kiro install` |
209213
| Pi coding agent | `graphify pi install` |
210214
| Devin CLI | `graphify devin install` |
@@ -571,6 +575,8 @@ graphify hermes install # AGENTS.md + ~/.hermes/skills/ (Hermes)
571575
graphify hermes uninstall
572576
graphify amp install # skill file (Amp)
573577
graphify amp uninstall
578+
graphify agents install # ~/.agents/skills/ + AGENTS.md (cross-framework; alias: graphify skills)
579+
graphify agents uninstall
574580
graphify kiro install # .kiro/skills/ + .kiro/steering/graphify.md (Kiro IDE/CLI)
575581
graphify kiro uninstall
576582
graphify pi install # skill file (Pi coding agent)

graphify/__main__.py

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ def _platform_skill_destination(platform_name: str, *, project: bool = False, pr
171171
return (project_dir or Path(".")) / ".agents" / "skills" / "graphify" / "SKILL.md"
172172
return Path.home() / ".config" / "agents" / "skills" / "graphify" / "SKILL.md"
173173

174+
if platform_name == "agents":
175+
# The generic Agent-Skills target: project ./.agents/skills, global the
176+
# spec's user-global ~/.agents/skills (read by `npx skills` and compliant
177+
# frameworks), NOT amp's ~/.config/agents/skills.
178+
if project:
179+
return (project_dir or Path(".")) / ".agents" / "skills" / "graphify" / "SKILL.md"
180+
return Path.home() / ".agents" / "skills" / "graphify" / "SKILL.md"
181+
174182
if platform_name in ("antigravity", "antigravity-windows"):
175183
if project:
176184
return (project_dir or Path(".")) / ".agents" / "skills" / "graphify" / "SKILL.md"
@@ -550,6 +558,16 @@ def _skill_registration(skill_path: str = "~/.claude/skills/graphify/SKILL.md")
550558
"claude_md": False,
551559
"skill_refs": "amp",
552560
},
561+
"agents": {
562+
# The generic cross-framework Agent-Skills target. Global: ~/.agents/skills
563+
# (the spec's user-global location, read by `npx skills` and compliant
564+
# frameworks); project: ./.agents/skills. The CLI accepts `skills` as an
565+
# alias (see _canonical_platform). Ships its own rendered bundle.
566+
"skill_file": "skill-agents.md",
567+
"skill_dst": Path(".agents") / "skills" / "graphify" / "SKILL.md",
568+
"claude_md": False,
569+
"skill_refs": "agents",
570+
},
553571
"devin": {
554572
# Monolith: devin ships the full SKILL.md inline, no references/ sidecar.
555573
"skill_file": "skill-devin.md",
@@ -560,6 +578,16 @@ def _skill_registration(skill_path: str = "~/.claude/skills/graphify/SKILL.md")
560578
},
561579
}
562580

581+
# CLI-only platform aliases, resolved to a real _PLATFORM_CONFIG key before
582+
# dispatch. `skills` is the friendly alias for the generic `agents` platform
583+
# (the Agent-Skills ecosystem calls them "skills").
584+
_PLATFORM_ALIASES: dict[str, str] = {"skills": "agents"}
585+
586+
587+
def _canonical_platform(platform_name: str) -> str:
588+
"""Resolve a CLI platform alias to its real _PLATFORM_CONFIG key."""
589+
return _PLATFORM_ALIASES.get(platform_name, platform_name)
590+
563591

564592
def _replace_or_append_section(content: str, marker: str, new_section: str) -> str:
565593
"""Idempotently update or append a graphify-owned section in shared files.
@@ -638,6 +666,7 @@ def _print_banner() -> None:
638666

639667
def install(platform: str = "claude", *, project: bool = False, project_dir: Path | None = None) -> None:
640668
_print_banner()
669+
platform = _canonical_platform(platform)
641670
if platform == "gemini":
642671
gemini_install(project_dir=project_dir, project=project)
643672
return
@@ -1627,9 +1656,32 @@ def _amp_uninstall(project_dir: Path | None = None) -> None:
16271656
_agents_uninstall(project_dir or Path("."), platform="amp")
16281657

16291658

1659+
def _agents_platform_install(project_dir: Path | None = None) -> None:
1660+
"""`graphify agents install`: skill into ~/.agents/skills + AGENTS.md.
1661+
1662+
The amp-twin of the generic Agent-Skills target. Mirrors _amp_install but
1663+
lands the skill at the spec's user-global ~/.agents/skills (set in
1664+
_platform_skill_destination). Wiring AGENTS.md keeps it honest with the
1665+
rendered hooks reference, which points at `graphify agents install`. The bare
1666+
`graphify install --platform agents` path stays skill-only (via install()),
1667+
exactly as amp's `--platform amp` does.
1668+
"""
1669+
_copy_skill_file("agents")
1670+
_agents_install(project_dir or Path("."), "agents")
1671+
1672+
1673+
def _agents_platform_uninstall(project_dir: Path | None = None) -> None:
1674+
"""`graphify agents uninstall`: remove the skill and the AGENTS.md section."""
1675+
removed = _remove_skill_file("agents")
1676+
if removed:
1677+
print("skill removed")
1678+
_agents_uninstall(project_dir or Path("."), platform="agents")
1679+
1680+
16301681
def _project_install(platform_name: str, project_dir: Path | None = None) -> None:
16311682
"""Install platform skill/config files in the current project."""
16321683
project_dir = project_dir or Path(".")
1684+
platform_name = _canonical_platform(platform_name)
16331685
if platform_name in ("claude", "windows"):
16341686
install(platform=platform_name, project=True, project_dir=project_dir)
16351687
claude_install(project_dir)
@@ -1662,7 +1714,9 @@ def _project_install(platform_name: str, project_dir: Path | None = None) -> Non
16621714
skill_dst = _copy_skill_file("antigravity", project=True, project_dir=project_dir)
16631715
_antigravity_finalize(skill_dst, project_dir)
16641716
_print_project_git_add_hint([_project_scope_root(skill_dst, project_dir), project_dir / ".agents"])
1665-
elif platform_name in ("copilot", "pi", "kimi"):
1717+
elif platform_name in ("copilot", "pi", "kimi", "agents"):
1718+
# Skill-only project install: drop SKILL.md (+ references) at the scope
1719+
# root. `agents` -> ./.agents/skills/graphify/SKILL.md.
16661720
skill_dst = _copy_skill_file(platform_name, project=True, project_dir=project_dir)
16671721
_print_project_git_add_hint([_project_scope_root(skill_dst, project_dir)])
16681722
else:
@@ -1672,6 +1726,7 @@ def _project_install(platform_name: str, project_dir: Path | None = None) -> Non
16721726
def _project_uninstall(platform_name: str, project_dir: Path | None = None) -> None:
16731727
"""Remove project-scoped platform skill/config files only."""
16741728
project_dir = project_dir or Path(".")
1729+
platform_name = _canonical_platform(platform_name)
16751730
if platform_name in ("claude", "windows"):
16761731
_remove_skill_file(platform_name, project=True, project_dir=project_dir)
16771732
_remove_claude_skill_registration(project_dir)
@@ -1694,7 +1749,7 @@ def _project_uninstall(platform_name: str, project_dir: Path | None = None) -> N
16941749
_devin_rules_uninstall(project_dir)
16951750
if not removed:
16961751
print("nothing to remove")
1697-
elif platform_name in ("copilot", "pi", "kimi"):
1752+
elif platform_name in ("copilot", "pi", "kimi", "agents"):
16981753
removed = _remove_skill_file(platform_name, project=True, project_dir=project_dir)
16991754
if not removed:
17001755
print("nothing to remove")
@@ -1885,6 +1940,9 @@ def uninstall_all(project_dir: Path | None = None, purge: bool = False) -> None:
18851940
# Amp also drops a user-scope skill at ~/.config/agents/skills, which the
18861941
# AGENTS.md cleanup above does not touch.
18871942
_remove_skill_file("amp")
1943+
# The generic agents platform's user-scope skill lives at ~/.agents/skills,
1944+
# which neither the AGENTS.md cleanup nor amp's removal reaches.
1945+
_remove_skill_file("agents")
18881946
_uninstall_opencode_plugin(pd)
18891947
_uninstall_codex_hook(pd)
18901948

@@ -2131,7 +2189,7 @@ def main() -> None:
21312189
print("Usage: graphify <command>")
21322190
print()
21332191
print("Commands:")
2134-
print(" install [--platform P] copy skill to platform config dir (claude|windows|codebuddy|codex|opencode|aider|amp|claw|droid|trae|trae-cn|gemini|cursor|antigravity|hermes|kiro|pi|devin)")
2192+
print(" install [--platform P] copy skill to platform config dir (claude|windows|codebuddy|codex|opencode|aider|amp|agents|claw|droid|trae|trae-cn|gemini|cursor|antigravity|hermes|kiro|pi|devin)")
21352193
print(" uninstall remove graphify from all detected platforms in one shot")
21362194
print(" --purge also delete graphify-out/ directory")
21372195
print(" path \"A\" \"B\" shortest path between two nodes in graph.json")
@@ -2517,6 +2575,21 @@ def main() -> None:
25172575
else:
25182576
print("Usage: graphify amp [install|uninstall]", file=sys.stderr)
25192577
sys.exit(1)
2578+
elif cmd in ("agents", "skills"):
2579+
subcmd = sys.argv[2] if len(sys.argv) > 2 else ""
2580+
if subcmd == "install":
2581+
if "--project" in sys.argv[3:]:
2582+
_project_install("agents", Path("."))
2583+
else:
2584+
_agents_platform_install(Path("."))
2585+
elif subcmd == "uninstall":
2586+
if "--project" in sys.argv[3:]:
2587+
_project_uninstall("agents", Path("."))
2588+
else:
2589+
_agents_platform_uninstall(Path("."))
2590+
else:
2591+
print(f"Usage: graphify {cmd} [install|uninstall]", file=sys.stderr)
2592+
sys.exit(1)
25202593
elif cmd in ("aider", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes"):
25212594
subcmd = sys.argv[2] if len(sys.argv) > 2 else ""
25222595
if subcmd == "install":

0 commit comments

Comments
 (0)