graphifyy 0.3.2__tar.gz → 0.3.4__tar.gz

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.
Files changed (60) hide show
  1. {graphifyy-0.3.2 → graphifyy-0.3.4}/PKG-INFO +8 -2
  2. {graphifyy-0.3.2 → graphifyy-0.3.4}/README.md +7 -1
  3. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/__main__.py +29 -21
  4. graphifyy-0.3.4/graphify/skill-windows.md +1207 -0
  5. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphifyy.egg-info/PKG-INFO +8 -2
  6. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphifyy.egg-info/SOURCES.txt +1 -0
  7. {graphifyy-0.3.2 → graphifyy-0.3.4}/pyproject.toml +2 -2
  8. {graphifyy-0.3.2 → graphifyy-0.3.4}/LICENSE +0 -0
  9. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/__init__.py +0 -0
  10. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/analyze.py +0 -0
  11. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/benchmark.py +0 -0
  12. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/build.py +0 -0
  13. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/cache.py +0 -0
  14. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/cluster.py +0 -0
  15. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/detect.py +0 -0
  16. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/export.py +0 -0
  17. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/extract.py +0 -0
  18. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/hooks.py +0 -0
  19. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/ingest.py +0 -0
  20. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/manifest.py +0 -0
  21. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/report.py +0 -0
  22. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/security.py +0 -0
  23. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/serve.py +0 -0
  24. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/skill-claw.md +0 -0
  25. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/skill-codex.md +0 -0
  26. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/skill-opencode.md +0 -0
  27. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/skill.md +0 -0
  28. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/validate.py +0 -0
  29. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/watch.py +0 -0
  30. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphify/wiki.py +0 -0
  31. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphifyy.egg-info/dependency_links.txt +0 -0
  32. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphifyy.egg-info/entry_points.txt +0 -0
  33. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphifyy.egg-info/requires.txt +0 -0
  34. {graphifyy-0.3.2 → graphifyy-0.3.4}/graphifyy.egg-info/top_level.txt +0 -0
  35. {graphifyy-0.3.2 → graphifyy-0.3.4}/setup.cfg +0 -0
  36. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_analyze.py +0 -0
  37. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_benchmark.py +0 -0
  38. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_build.py +0 -0
  39. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_cache.py +0 -0
  40. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_claude_md.py +0 -0
  41. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_cluster.py +0 -0
  42. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_confidence.py +0 -0
  43. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_detect.py +0 -0
  44. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_export.py +0 -0
  45. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_extract.py +0 -0
  46. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_hooks.py +0 -0
  47. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_hypergraph.py +0 -0
  48. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_ingest.py +0 -0
  49. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_install.py +0 -0
  50. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_languages.py +0 -0
  51. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_multilang.py +0 -0
  52. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_pipeline.py +0 -0
  53. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_rationale.py +0 -0
  54. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_report.py +0 -0
  55. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_security.py +0 -0
  56. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_semantic_similarity.py +0 -0
  57. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_serve.py +0 -0
  58. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_validate.py +0 -0
  59. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_watch.py +0 -0
  60. {graphifyy-0.3.2 → graphifyy-0.3.4}/tests/test_wiki.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphifyy
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: AI coding assistant skill (Claude Code, Codex, OpenCode, OpenClaw) - turn any folder of code, docs, papers, or images into a queryable knowledge graph
5
5
  License: MIT License
6
6
 
@@ -76,6 +76,7 @@ Dynamic: license-file
76
76
 
77
77
  [![CI](https://github.com/safishamsi/graphify/actions/workflows/ci.yml/badge.svg?branch=v3)](https://github.com/safishamsi/graphify/actions/workflows/ci.yml)
78
78
  [![PyPI](https://img.shields.io/pypi/v/graphifyy)](https://pypi.org/project/graphifyy/)
79
+ [![Sponsor](https://img.shields.io/badge/sponsor-safishamsi-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/safishamsi)
79
80
 
80
81
  **An AI coding assistant skill.** Type `/graphify` in Claude Code, Codex, OpenCode, OpenClaw, or Factory Droid - it reads your files, builds a knowledge graph, and gives you back structure you didn't know was there. Understand a codebase faster. Find the "why" behind architectural decisions.
81
82
 
@@ -129,7 +130,8 @@ pip install graphifyy && graphify install
129
130
 
130
131
  | Platform | Install command |
131
132
  |----------|----------------|
132
- | Claude Code | `graphify install` |
133
+ | Claude Code (Linux/Mac) | `graphify install` |
134
+ | Claude Code (Windows) | `graphify install` (auto-detected) or `graphify install --platform windows` |
133
135
  | Codex | `graphify install --platform codex` |
134
136
  | OpenCode | `graphify install --platform opencode` |
135
137
  | OpenClaw | `graphify install --platform claw` |
@@ -282,6 +284,10 @@ graphify sends file contents to your AI coding assistant's underlying model API
282
284
 
283
285
  NetworkX + Leiden (graspologic) + tree-sitter + vis.js. Semantic extraction via Claude (Claude Code), GPT-4 (Codex), or whichever model your platform runs. No Neo4j required, no server, runs entirely locally.
284
286
 
287
+ ## Star history
288
+
289
+ [![Star History Chart](https://api.star-history.com/svg?repos=safishamsi/graphify&type=Date)](https://star-history.com/#safishamsi/graphify&Date)
290
+
285
291
  <details>
286
292
  <summary>Contributing</summary>
287
293
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  [![CI](https://github.com/safishamsi/graphify/actions/workflows/ci.yml/badge.svg?branch=v3)](https://github.com/safishamsi/graphify/actions/workflows/ci.yml)
6
6
  [![PyPI](https://img.shields.io/pypi/v/graphifyy)](https://pypi.org/project/graphifyy/)
7
+ [![Sponsor](https://img.shields.io/badge/sponsor-safishamsi-ea4aaa?logo=github-sponsors)](https://github.com/sponsors/safishamsi)
7
8
 
8
9
  **An AI coding assistant skill.** Type `/graphify` in Claude Code, Codex, OpenCode, OpenClaw, or Factory Droid - it reads your files, builds a knowledge graph, and gives you back structure you didn't know was there. Understand a codebase faster. Find the "why" behind architectural decisions.
9
10
 
@@ -57,7 +58,8 @@ pip install graphifyy && graphify install
57
58
 
58
59
  | Platform | Install command |
59
60
  |----------|----------------|
60
- | Claude Code | `graphify install` |
61
+ | Claude Code (Linux/Mac) | `graphify install` |
62
+ | Claude Code (Windows) | `graphify install` (auto-detected) or `graphify install --platform windows` |
61
63
  | Codex | `graphify install --platform codex` |
62
64
  | OpenCode | `graphify install --platform opencode` |
63
65
  | OpenClaw | `graphify install --platform claw` |
@@ -210,6 +212,10 @@ graphify sends file contents to your AI coding assistant's underlying model API
210
212
 
211
213
  NetworkX + Leiden (graspologic) + tree-sitter + vis.js. Semantic extraction via Claude (Claude Code), GPT-4 (Codex), or whichever model your platform runs. No Neo4j required, no server, runs entirely locally.
212
214
 
215
+ ## Star history
216
+
217
+ [![Star History Chart](https://api.star-history.com/svg?repos=safishamsi/graphify&type=Date)](https://star-history.com/#safishamsi/graphify&Date)
218
+
213
219
  <details>
214
220
  <summary>Contributing</summary>
215
221
 
@@ -1,6 +1,7 @@
1
1
  """graphify CLI - `graphify install` sets up the Claude Code skill."""
2
2
  from __future__ import annotations
3
3
  import json
4
+ import platform
4
5
  import re
5
6
  import shutil
6
7
  import sys
@@ -55,6 +56,11 @@ _PLATFORM_CONFIG: dict[str, dict] = {
55
56
  "skill_dst": Path(".factory") / "skills" / "graphify" / "SKILL.md",
56
57
  "claude_md": False,
57
58
  },
59
+ "windows": {
60
+ "skill_file": "skill-windows.md",
61
+ "skill_dst": Path(".claude") / "skills" / "graphify" / "SKILL.md",
62
+ "claude_md": True,
63
+ },
58
64
  }
59
65
 
60
66
 
@@ -81,15 +87,15 @@ def install(platform: str = "claude") -> None:
81
87
  # Register in ~/.claude/CLAUDE.md (Claude Code only)
82
88
  claude_md = Path.home() / ".claude" / "CLAUDE.md"
83
89
  if claude_md.exists():
84
- content = claude_md.read_text()
90
+ content = claude_md.read_text(encoding="utf-8")
85
91
  if "graphify" in content:
86
92
  print(f" CLAUDE.md → already registered (no change)")
87
93
  else:
88
- claude_md.write_text(content.rstrip() + _SKILL_REGISTRATION)
94
+ claude_md.write_text(content.rstrip() + _SKILL_REGISTRATION, encoding="utf-8")
89
95
  print(f" CLAUDE.md → skill registered in {claude_md}")
90
96
  else:
91
97
  claude_md.parent.mkdir(parents=True, exist_ok=True)
92
- claude_md.write_text(_SKILL_REGISTRATION.lstrip())
98
+ claude_md.write_text(_SKILL_REGISTRATION.lstrip(), encoding="utf-8")
93
99
  print(f" CLAUDE.md → created at {claude_md}")
94
100
 
95
101
  print()
@@ -133,7 +139,7 @@ def _agents_install(project_dir: Path, platform: str) -> None:
133
139
  target = (project_dir or Path(".")) / "AGENTS.md"
134
140
 
135
141
  if target.exists():
136
- content = target.read_text()
142
+ content = target.read_text(encoding="utf-8")
137
143
  if _AGENTS_MD_MARKER in content:
138
144
  print(f"graphify already configured in AGENTS.md")
139
145
  return
@@ -141,7 +147,7 @@ def _agents_install(project_dir: Path, platform: str) -> None:
141
147
  else:
142
148
  new_content = _AGENTS_MD_SECTION
143
149
 
144
- target.write_text(new_content)
150
+ target.write_text(new_content, encoding="utf-8")
145
151
  print(f"graphify section written to {target.resolve()}")
146
152
  print()
147
153
  print(f"{platform.capitalize()} will now check the knowledge graph before answering")
@@ -159,7 +165,7 @@ def _agents_uninstall(project_dir: Path) -> None:
159
165
  print("No AGENTS.md found in current directory - nothing to do")
160
166
  return
161
167
 
162
- content = target.read_text()
168
+ content = target.read_text(encoding="utf-8")
163
169
  if _AGENTS_MD_MARKER not in content:
164
170
  print("graphify section not found in AGENTS.md - nothing to do")
165
171
  return
@@ -171,7 +177,7 @@ def _agents_uninstall(project_dir: Path) -> None:
171
177
  flags=re.DOTALL,
172
178
  ).rstrip()
173
179
  if cleaned:
174
- target.write_text(cleaned + "\n")
180
+ target.write_text(cleaned + "\n", encoding="utf-8")
175
181
  print(f"graphify section removed from {target.resolve()}")
176
182
  else:
177
183
  target.unlink()
@@ -183,7 +189,7 @@ def claude_install(project_dir: Path | None = None) -> None:
183
189
  target = (project_dir or Path(".")) / "CLAUDE.md"
184
190
 
185
191
  if target.exists():
186
- content = target.read_text()
192
+ content = target.read_text(encoding="utf-8")
187
193
  if _CLAUDE_MD_MARKER in content:
188
194
  print("graphify already configured in CLAUDE.md")
189
195
  return
@@ -191,7 +197,7 @@ def claude_install(project_dir: Path | None = None) -> None:
191
197
  else:
192
198
  new_content = _CLAUDE_MD_SECTION
193
199
 
194
- target.write_text(new_content)
200
+ target.write_text(new_content, encoding="utf-8")
195
201
  print(f"graphify section written to {target.resolve()}")
196
202
 
197
203
  # Also write Claude Code PreToolUse hook to .claude/settings.json
@@ -209,7 +215,7 @@ def _install_claude_hook(project_dir: Path) -> None:
209
215
 
210
216
  if settings_path.exists():
211
217
  try:
212
- settings = json.loads(settings_path.read_text())
218
+ settings = json.loads(settings_path.read_text(encoding="utf-8"))
213
219
  except json.JSONDecodeError:
214
220
  settings = {}
215
221
  else:
@@ -224,7 +230,7 @@ def _install_claude_hook(project_dir: Path) -> None:
224
230
  return
225
231
 
226
232
  pre_tool.append(_SETTINGS_HOOK)
227
- settings_path.write_text(json.dumps(settings, indent=2))
233
+ settings_path.write_text(json.dumps(settings, indent=2), encoding="utf-8")
228
234
  print(f" .claude/settings.json → PreToolUse hook registered")
229
235
 
230
236
 
@@ -234,7 +240,7 @@ def _uninstall_claude_hook(project_dir: Path) -> None:
234
240
  if not settings_path.exists():
235
241
  return
236
242
  try:
237
- settings = json.loads(settings_path.read_text())
243
+ settings = json.loads(settings_path.read_text(encoding="utf-8"))
238
244
  except json.JSONDecodeError:
239
245
  return
240
246
  pre_tool = settings.get("hooks", {}).get("PreToolUse", [])
@@ -242,7 +248,7 @@ def _uninstall_claude_hook(project_dir: Path) -> None:
242
248
  if len(filtered) == len(pre_tool):
243
249
  return
244
250
  settings["hooks"]["PreToolUse"] = filtered
245
- settings_path.write_text(json.dumps(settings, indent=2))
251
+ settings_path.write_text(json.dumps(settings, indent=2), encoding="utf-8")
246
252
  print(f" .claude/settings.json → PreToolUse hook removed")
247
253
 
248
254
 
@@ -254,7 +260,7 @@ def claude_uninstall(project_dir: Path | None = None) -> None:
254
260
  print("No CLAUDE.md found in current directory - nothing to do")
255
261
  return
256
262
 
257
- content = target.read_text()
263
+ content = target.read_text(encoding="utf-8")
258
264
  if _CLAUDE_MD_MARKER not in content:
259
265
  print("graphify section not found in CLAUDE.md - nothing to do")
260
266
  return
@@ -267,7 +273,7 @@ def claude_uninstall(project_dir: Path | None = None) -> None:
267
273
  flags=re.DOTALL,
268
274
  ).rstrip()
269
275
  if cleaned:
270
- target.write_text(cleaned + "\n")
276
+ target.write_text(cleaned + "\n", encoding="utf-8")
271
277
  print(f"graphify section removed from {target.resolve()}")
272
278
  else:
273
279
  target.unlink()
@@ -281,7 +287,7 @@ def main() -> None:
281
287
  print("Usage: graphify <command>")
282
288
  print()
283
289
  print("Commands:")
284
- print(" install [--platform P] copy skill to platform config dir (claude|codex|opencode|claw|droid)")
290
+ print(" install [--platform P] copy skill to platform config dir (claude|windows|codex|opencode|claw|droid)")
285
291
  print(" benchmark [graph.json] measure token reduction vs naive full-corpus approach")
286
292
  print(" hook install install post-commit/post-checkout git hooks (all platforms)")
287
293
  print(" hook uninstall remove git hooks")
@@ -301,19 +307,21 @@ def main() -> None:
301
307
 
302
308
  cmd = sys.argv[1]
303
309
  if cmd == "install":
304
- platform = "claude"
310
+ # Default to windows platform on Windows, claude elsewhere
311
+ default_platform = "windows" if platform.system() == "Windows" else "claude"
312
+ chosen_platform = default_platform
305
313
  args = sys.argv[2:]
306
314
  i = 0
307
315
  while i < len(args):
308
316
  if args[i].startswith("--platform="):
309
- platform = args[i].split("=", 1)[1]
317
+ chosen_platform = args[i].split("=", 1)[1]
310
318
  i += 1
311
319
  elif args[i] == "--platform" and i + 1 < len(args):
312
- platform = args[i + 1]
320
+ chosen_platform = args[i + 1]
313
321
  i += 2
314
322
  else:
315
323
  i += 1
316
- install(platform=platform)
324
+ install(platform=chosen_platform)
317
325
  elif cmd == "claude":
318
326
  subcmd = sys.argv[2] if len(sys.argv) > 2 else ""
319
327
  if subcmd == "install":
@@ -352,7 +360,7 @@ def main() -> None:
352
360
  detect_path = Path(".graphify_detect.json")
353
361
  if detect_path.exists():
354
362
  try:
355
- detect_data = json.loads(detect_path.read_text())
363
+ detect_data = json.loads(detect_path.read_text(encoding="utf-8"))
356
364
  corpus_words = detect_data.get("total_words")
357
365
  except Exception:
358
366
  pass