Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu

## 0.9.36 (unreleased)

- Feature: new supported platform — Command Code (`graphify install --platform command-code`). The skill installs to `~/.commandcode/skills/graphify/` (user) or `.commandcode/skills/graphify/` (`--project`) with the full `references/` sidecar, and `graphify command-code install` wires the always-on `## graphify` section into `AGENTS.md`.
- Fix: four commands that failed silently while exiting 0 now surface the problem (#2534, thanks @elecnix). `cluster-only` warns when `--backend`/`--model`/`--batch-size` are ignored because saved labels are being reused; the community-label prompt no longer collides with the discard sentinel (a model echoing the key back is no longer silently dropped); `tree --root` exits non-zero when the root matches no source file instead of silently flattening the tree; and `cluster-only` stamps `built_at_commit` from the analysed graph rather than the shell's working directory. Also folds in the `cluster-only` refused-write guard from #2522 (thanks @aniJani).
- Fix: a Swift `extension Foo` in a different file from `Foo` no longer drops static and singleton call edges into the type (#2538, thanks @pawelo446). The extension node id is now remapped consistently so the extension merges onto its base type before call resolution, and the merge is gated so it never absorbs a same-named type from another language.
- Fix: node-id collision resolution is now deterministic and prefers active over archived paths (#2532, thanks @michaelxer for the active/archived idea in #2540). Two files that mint the same id (for example `plans/_done/x.md` vs `plans/in-progress/x.md`) are ranked by a lifecycle penalty computed on the root-relative path and a reversed-segment tie-break, so the winner no longer depends on ASCII filename order, absolute-vs-relative path form, or the checkout directory name.
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ graphify-out/
└── graph.json the full graph — query it anytime without re-reading your files
```

**Works in** Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot, and 15+ more — [pick your platform](#install).
**Works in** Claude Code, Cursor, Codex, Gemini CLI, GitHub Copilot, Command Code, and 15+ more — [pick your platform](#install).

---

Expand Down Expand Up @@ -229,6 +229,7 @@ for example `graphify claude install --project` or `graphify codex install --pro
| Agent Skills (cross-framework) | `graphify install --platform agents` (alias `--platform skills`) |
| Kiro IDE/CLI | `graphify kiro install` |
| Pi coding agent | `graphify install --platform pi` |
| Command Code | `graphify install --platform command-code` |
| Cursor | `graphify cursor install` |
| Devin CLI | `graphify devin install` |
| Google Antigravity | `graphify antigravity install` |
Expand Down Expand Up @@ -299,6 +300,7 @@ Run this once in your project after building a graph:
| Agent Skills (cross-framework) | `graphify agents install` (alias `graphify skills install`) |
| Kiro IDE/CLI | `graphify kiro install` |
| Pi coding agent | `graphify pi install` |
| Command Code | `graphify command-code install` |
| Devin CLI | `graphify devin install` |
| Google Antigravity | `graphify antigravity install` |

Expand Down Expand Up @@ -716,6 +718,8 @@ graphify pi install # skill file (Pi coding agent)
graphify pi uninstall
graphify devin install # skill file + .windsurf/rules/graphify.md (Devin CLI)
graphify devin uninstall
graphify command-code install # ~/.commandcode/skills/ + AGENTS.md (Command Code)
graphify command-code uninstall
graphify antigravity install # .agents/rules + .agents/workflows (Google Antigravity)
graphify antigravity uninstall

Expand Down
4 changes: 3 additions & 1 deletion graphify/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ def _run_cli() -> None:
print("Usage: graphify <command>")
print()
print("Commands:")
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)")
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|command-code)")
print(" uninstall remove graphify from all detected platforms in one shot")
print(" --purge also delete graphify-out/ directory")
print(" path \"A\" \"B\" shortest path between two nodes in graph.json")
Expand Down Expand Up @@ -692,6 +692,8 @@ def _run_cli() -> None:
print(" pi uninstall remove skill from ~/.pi/agent/skills/graphify/")
print(" devin install write skill to ~/.config/devin/skills/graphify/ (Devin CLI)")
print(" devin uninstall remove skill from ~/.config/devin/skills/graphify/")
print(" command-code install write skill to ~/.commandcode/skills/graphify/ + AGENTS.md (Command Code)")
print(" command-code uninstall remove skill from ~/.commandcode/skills/graphify/ + AGENTS.md section")
print()
return

Expand Down
26 changes: 23 additions & 3 deletions graphify/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ def _platform_skill_destination(platform_name: str, *, project: bool = False, pr
# Global Antigravity skill dir (all workspaces): ~/.gemini/config/skills/
return Path.home() / ".gemini" / "config" / "skills" / "graphify" / "SKILL.md"

if platform_name == "command-code":
if project:
return (project_dir or Path(".")) / ".commandcode" / "skills" / "graphify" / "SKILL.md"
if os.environ.get("COMMANDCODE_CONFIG_DIR"):
return Path(os.environ["COMMANDCODE_CONFIG_DIR"]) / "skills" / "graphify" / "SKILL.md"
return Path.home() / ".commandcode" / "skills" / "graphify" / "SKILL.md"

cfg = _PLATFORM_CONFIG[platform_name]
if project:
return (project_dir or Path(".")) / cfg["skill_dst"]
Expand Down Expand Up @@ -455,6 +462,15 @@ def _skill_registration(skill_path: str = "~/.claude/skills/graphify/SKILL.md")
"claude_md": False,
"skill_refs": "agents",
},
"command-code": {
# Command Code discovers skills from .commandcode/skills/ (project) and
# ~/.commandcode/skills/ (user-global). The user-scope path is set in
# _platform_skill_destination (COMMANDCODE_CONFIG_DIR override).
"skill_file": "skill-command-code.md",
"skill_dst": Path(".commandcode") / "skills" / "graphify" / "SKILL.md",
"claude_md": False,
"skill_refs": "command-code",
},
"devin": {
# Monolith: devin ships the full SKILL.md inline, no references/ sidecar.
"skill_file": "skill-devin.md",
Expand Down Expand Up @@ -1560,7 +1576,7 @@ def _project_install(platform_name: str, project_dir: Path | None = None, strict
elif platform_name == "kiro":
_kiro_install(project_dir)
_print_project_git_add_hint([project_dir / ".kiro"])
elif platform_name in ("aider", "amp", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes"):
elif platform_name in ("aider", "amp", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes", "command-code"):
skill_dst = _copy_skill_file(platform_name, project=True, project_dir=project_dir)
_agents_install(project_dir, platform_name)
hint_paths = [_project_scope_root(skill_dst, project_dir), project_dir / "AGENTS.md"]
Expand Down Expand Up @@ -1601,7 +1617,7 @@ def _project_uninstall(platform_name: str, project_dir: Path | None = None) -> N
_cursor_uninstall(project_dir)
elif platform_name == "kiro":
_kiro_uninstall(project_dir)
elif platform_name in ("aider", "amp", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes"):
elif platform_name in ("aider", "amp", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes", "command-code"):
_remove_skill_file(platform_name, project=True, project_dir=project_dir)
_agents_uninstall(project_dir, platform=platform_name)
if platform_name == "codex":
Expand Down Expand Up @@ -1798,6 +1814,9 @@ def uninstall_all(project_dir: Path | None = None, purge: bool = False) -> None:
# The generic agents platform's user-scope skill lives at ~/.agents/skills,
# which neither the AGENTS.md cleanup nor amp's removal reaches.
_remove_skill_file("agents")
# Command Code's user-scope skill lives at ~/.commandcode/skills, which the
# AGENTS.md cleanup does not touch either.
_remove_skill_file("command-code")
_uninstall_opencode_plugin(pd)
_uninstall_codex_hook(pd)

Expand Down Expand Up @@ -1994,6 +2013,7 @@ def codebuddy_uninstall(project_dir: Path | None = None, *, project: bool = Fals
"claw",
"codebuddy",
"codex",
"command-code",
"copilot",
"cursor",
"devin",
Expand Down Expand Up @@ -2256,7 +2276,7 @@ def dispatch_install_cli(cmd: str) -> bool:
else:
print(f"Usage: graphify {cmd} [install|uninstall]", file=sys.stderr)
sys.exit(1)
elif cmd in ("aider", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes"):
elif cmd in ("aider", "codex", "opencode", "claw", "droid", "trae", "trae-cn", "hermes", "command-code"):
subcmd = sys.argv[2] if len(sys.argv) > 2 else ""
if subcmd == "install":
if "--project" in sys.argv[3:]:
Expand Down
Loading