fix(install): route kiro install/uninstall through shared progressive helper (#1142)

_kiro_install was using a bare write_text that bypassed _copy_skill_file,
so the references/ sidecar and .graphify_version stamp were never written
despite kiro declaring skill_refs: "kiro". This left SKILL.md with 8 dead
references/*.md pointers on every install.

Fix: call _copy_skill_file("kiro", project=True) for the skill+sidecar+stamp,
keep the steering-file block inline. Uninstall now calls _remove_skill_file
which also cleans .graphify_version and references/.

Adds regression test asserting SKILL.md + references/ + .graphify_version +
no references.tmp + steering file, and that uninstall removes all of them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Safi
2026-06-05 22:15:09 +01:00
co-authored by Claude Sonnet 4.6
parent 6e860e018a
commit 3a4bdf54cc
2 changed files with 47 additions and 14 deletions
+8 -14
View File
@@ -901,12 +901,11 @@ def _kiro_install(project_dir: Path) -> None:
"""Write graphify skill + steering file for Kiro IDE/CLI."""
project_dir = project_dir or Path(".")
# Skill file → .kiro/skills/graphify/SKILL.md
skill_src = Path(__file__).parent / "skill-kiro.md"
skill_dst = project_dir / ".kiro" / "skills" / "graphify" / "SKILL.md"
skill_dst.parent.mkdir(parents=True, exist_ok=True)
skill_dst.write_text(skill_src.read_text(encoding="utf-8"), encoding="utf-8")
print(f" {skill_dst.relative_to(project_dir)} -> /graphify skill")
# Skill file + references/ sidecar + .graphify_version stamp via the shared
# progressive-disclosure helper. Previously this used a bare write_text that
# bypassed _copy_skill_file, so the references/ dir and version stamp were
# never written even though kiro declares skill_refs: "kiro" (#1142).
_copy_skill_file("kiro", project=True, project_dir=project_dir)
# Steering file → .kiro/steering/graphify.md (always-on)
steering_dir = project_dir / ".kiro" / "steering"
@@ -931,15 +930,10 @@ def _kiro_uninstall(project_dir: Path) -> None:
project_dir = project_dir or Path(".")
removed = []
skill_dst = project_dir / ".kiro" / "skills" / "graphify" / "SKILL.md"
if skill_dst.exists():
skill_dst.unlink()
# Skill + .graphify_version + references/ sidecar + empty-dir walk.
skill_dst = _platform_skill_destination("kiro", project=True, project_dir=project_dir)
if _remove_skill_file("kiro", project=True, project_dir=project_dir):
removed.append(str(skill_dst.relative_to(project_dir)))
# Remove parent dir if empty
try:
skill_dst.parent.rmdir()
except OSError:
pass
steering_dst = project_dir / ".kiro" / "steering" / "graphify.md"
if steering_dst.exists():
+39
View File
@@ -231,3 +231,42 @@ def test_kiro_install_upgrades_stale_steering(tmp_path, monkeypatch):
assert "read it before answering architecture questions" not in after
_assert_query_first(after, ".kiro/steering/graphify.md")
assert "inclusion: always" in after # frontmatter preserved
def test_kiro_install_ships_references_sidecar_and_version_stamp(tmp_path, monkeypatch):
"""_kiro_install routes through _copy_skill_file so the references/ sidecar
and .graphify_version stamp are written alongside SKILL.md (#1142).
Previously it used a bare write_text that bypassed the shared helper."""
monkeypatch.setattr(mainmod, "_check_skill_version", lambda _: None)
refs_dir = Path(mainmod.__file__).parent / "skills" / "kiro" / "references"
if not refs_dir.exists():
pytest.skip("kiro references bundle not present in this checkout")
mainmod._kiro_install(tmp_path)
skill_dir = tmp_path / ".kiro" / "skills" / "graphify"
# SKILL.md present
assert (skill_dir / "SKILL.md").exists()
# references/ sidecar installed with at least one fragment
refs_dst = skill_dir / "references"
assert refs_dst.is_dir(), "references/ sidecar must be installed (#1142)"
assert any(refs_dst.iterdir()), "references/ must not be empty"
# .graphify_version stamp written
version_file = skill_dir / ".graphify_version"
assert version_file.exists(), ".graphify_version stamp must be written (#1142)"
assert version_file.read_text(encoding="utf-8") == mainmod.__version__
# no references.tmp leftover
assert not (skill_dir / "references.tmp").exists()
# steering file still written
assert (tmp_path / ".kiro" / "steering" / "graphify.md").exists()
# uninstall removes skill dir, version stamp, references/, and steering file
mainmod._kiro_uninstall(tmp_path)
assert not skill_dir.exists(), "uninstall must remove skill dir including references/ (#1142)"
assert not (tmp_path / ".kiro" / "steering" / "graphify.md").exists()