codex-coach 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-coach",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Local-first Codex usage coach that analyzes logs and suggests workflow improvements.",
5
5
  "author": {
6
6
  "name": "Codex Coach Contributors"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-coach",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Local-first Codex usage coach and plugin",
5
5
  "license": "MIT",
6
6
  "author": "Codex Coach Contributors",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "codex-coach"
7
- version = "0.1.4"
7
+ version = "0.1.5"
8
8
  description = "Local-first Codex usage coach and plugin"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """Local-first Codex usage coach."""
2
2
 
3
- __version__ = "0.1.4"
3
+ __version__ = "0.1.5"
@@ -166,8 +166,11 @@ def _doctor(paths) -> int:
166
166
  print(f"command: {command} {'OK' if command.exists() else 'not installed'}")
167
167
  plugin = paths.home / "plugins" / "codex-coach" / ".codex-plugin" / "plugin.json"
168
168
  print(f"plugin: {plugin} {'OK' if plugin.exists() else 'not installed'}")
169
- skill = paths.home / ".agents" / "skills" / "codex-coach" / "SKILL.md"
169
+ skill = paths.codex_home / "skills" / "codex-coach" / "SKILL.md"
170
+ legacy_skill = paths.home / ".agents" / "skills" / "codex-coach" / "SKILL.md"
170
171
  print(f"skill: {skill} {'OK' if skill.exists() else 'not installed'}")
172
+ if legacy_skill.exists():
173
+ print(f"legacy_skill: {legacy_skill} duplicate")
171
174
  return 0 if paths.codex_home.exists() else 1
172
175
 
173
176
 
@@ -19,7 +19,7 @@ def install_from_source(source_root: Path, paths: CoachPaths, *, schedule: str =
19
19
  _copy_app(source_root, paths.app_dir)
20
20
  _install_command(paths)
21
21
  plugin_path = _install_plugin(source_root, paths.home)
22
- skill_paths = _install_user_skills(source_root, paths.home)
22
+ skill_paths = _install_user_skills(source_root, paths)
23
23
  marketplace = _update_marketplace(paths.home, plugin_path)
24
24
  scheduler = _write_scheduler(paths, schedule=schedule)
25
25
  return {
@@ -90,20 +90,28 @@ def _install_plugin(source_root: Path, home: Path) -> Path:
90
90
  return plugin_root
91
91
 
92
92
 
93
- def _install_user_skills(source_root: Path, home: Path) -> list[Path]:
93
+ def _install_user_skills(source_root: Path, paths: CoachPaths) -> list[Path]:
94
94
  skill_source = source_root / "skills" / PLUGIN_NAME
95
- targets = [
96
- home / ".agents" / "skills" / PLUGIN_NAME,
97
- home / ".codex" / "skills" / PLUGIN_NAME,
98
- ]
99
- installed: list[Path] = []
100
- for target in targets:
101
- if target.exists():
102
- shutil.rmtree(target)
103
- target.parent.mkdir(parents=True, exist_ok=True)
104
- shutil.copytree(skill_source, target)
105
- installed.append(target)
106
- return installed
95
+ target = paths.codex_home / "skills" / PLUGIN_NAME
96
+ if target.exists():
97
+ shutil.rmtree(target)
98
+ target.parent.mkdir(parents=True, exist_ok=True)
99
+ shutil.copytree(skill_source, target)
100
+ _remove_legacy_duplicate_skill(paths.home, target)
101
+ return [target]
102
+
103
+
104
+ def _remove_legacy_duplicate_skill(home: Path, canonical_target: Path) -> None:
105
+ legacy_target = home / ".agents" / "skills" / PLUGIN_NAME
106
+ if legacy_target.resolve() == canonical_target.resolve() or not legacy_target.exists():
107
+ return
108
+ skill_file = legacy_target / "SKILL.md"
109
+ try:
110
+ skill_text = skill_file.read_text(encoding="utf-8")
111
+ except OSError:
112
+ return
113
+ if f"name: {PLUGIN_NAME}" in skill_text:
114
+ shutil.rmtree(legacy_target)
107
115
 
108
116
 
109
117
  def _update_marketplace(home: Path, plugin_path: Path) -> Path: