graphifyy 0.9.4__tar.gz → 0.9.6__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.
- {graphifyy-0.9.4/graphifyy.egg-info → graphifyy-0.9.6}/PKG-INFO +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/README.md +1 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/__main__.py +77 -5
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/analyze.py +1 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/build.py +8 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/cluster.py +21 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/detect.py +31 -14
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/export.py +7 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extract.py +1041 -71
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/base.py +8 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/elixir.py +30 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/hooks.py +38 -9
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/llm.py +84 -19
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/ruby_resolution.py +31 -3
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/serve.py +150 -52
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-agents.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-aider.md +1 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-amp.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-claw.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-codex.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-copilot.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-devin.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-droid.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-kilo.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-kiro.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-opencode.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-pi.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-trae.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-vscode.md +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill-windows.md +1 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skill.md +2 -2
- {graphifyy-0.9.4/graphify/skills/amp → graphifyy-0.9.6/graphify/skills/agents}/references/query.md +5 -5
- {graphifyy-0.9.4/graphify/skills/claude → graphifyy-0.9.6/graphify/skills/amp}/references/query.md +5 -5
- {graphifyy-0.9.4/graphify/skills/claw → graphifyy-0.9.6/graphify/skills/claude}/references/query.md +5 -5
- {graphifyy-0.9.4/graphify/skills/agents → graphifyy-0.9.6/graphify/skills/claw}/references/query.md +5 -5
- graphifyy-0.9.6/graphify/skills/codex/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/copilot/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/droid/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/kilo/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/kiro/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/opencode/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/pi/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/trae/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/vscode/references/query.md +311 -0
- graphifyy-0.9.6/graphify/skills/windows/references/query.md +311 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/watch.py +277 -112
- {graphifyy-0.9.4 → graphifyy-0.9.6/graphifyy.egg-info}/PKG-INFO +2 -2
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphifyy.egg-info/SOURCES.txt +12 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/pyproject.toml +1 -1
- graphifyy-0.9.6/tests/test_case_sensitive_resolution.py +87 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_chunking.py +47 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_claude_cli_backend.py +37 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_cli_export.py +30 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_community_hub_labels.py +17 -0
- graphifyy-0.9.6/tests/test_csharp_member_calls.py +143 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_detect.py +34 -11
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_extract.py +26 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_hooks.py +44 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_image_vision.py +31 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_indirect_dispatch.py +27 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_languages.py +134 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_llm_parser.py +19 -10
- graphifyy-0.9.6/tests/test_merge_graphs_cli.py +48 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_multilang.py +26 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_obsidian_dangling_member.py +20 -0
- graphifyy-0.9.6/tests/test_phantom_external_import.py +116 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_ruby_resolution.py +97 -0
- graphifyy-0.9.6/tests/test_semantic_fragment_sanitize.py +71 -0
- graphifyy-0.9.6/tests/test_semantic_id_remap_root.py +50 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_serve.py +50 -1
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_serve_http.py +69 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_swift_cross_file_calls.py +25 -0
- graphifyy-0.9.6/tests/test_ts_decorators.py +153 -0
- graphifyy-0.9.6/tests/test_ts_generators.py +74 -0
- graphifyy-0.9.6/tests/test_ts_import_require.py +119 -0
- graphifyy-0.9.6/tests/test_ts_namespace.py +73 -0
- graphifyy-0.9.6/tests/test_ts_receiver_member_calls.py +81 -0
- graphifyy-0.9.6/tests/test_typescript_module_extensions.py +84 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_watch.py +380 -0
- graphifyy-0.9.4/graphify/skills/codex/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/copilot/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/droid/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/kilo/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/kiro/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/opencode/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/pi/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/trae/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/vscode/references/query.md +0 -311
- graphifyy-0.9.4/graphify/skills/windows/references/query.md +0 -311
- {graphifyy-0.9.4 → graphifyy-0.9.6}/LICENSE +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/__init__.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/_minhash.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/affected.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/always_on/agents-md.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/always_on/antigravity-rules.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/always_on/claude-md.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/always_on/gemini-md.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/always_on/kiro-steering.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/always_on/vscode-instructions.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/benchmark.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/cache.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/callflow_html.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/cargo_introspect.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/command-kilo.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/dedup.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/diagnostics.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/__init__.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/blade.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/csharp.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/razor.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/extractors/zig.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/file_slice.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/global_graph.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/google_workspace.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/ids.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/manifest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/manifest_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/mcp_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/multigraph_compat.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/paths.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/pg_introspect.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/prs.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/querylog.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/reflect.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/report.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/resolver_registry.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/scip_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/security.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/semantic_cleanup.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/agents/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/amp/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claude/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/claw/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/codex/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/copilot/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/droid/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kilo/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/kiro/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/opencode/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/pi/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/trae/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/vscode/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/add-watch.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/exports.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/extraction-spec.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/github-and-merge.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/hooks.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/transcribe.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/skills/windows/references/update.md +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/symbol_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/transcribe.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/tree_html.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/validate.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphify/wiki.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphifyy.egg-info/dependency_links.txt +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphifyy.egg-info/entry_points.txt +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphifyy.egg-info/requires.txt +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/graphifyy.egg-info/top_level.txt +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/setup.cfg +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_affected_cli.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_agents_platform.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_analyze.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_anthropic_custom_endpoint.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_antigravity_install.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_astro_extraction.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_backend_extras.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_benchmark.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_build.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_build_merge_hyperedges_and_prune.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_cache.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_callflow_html.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_cargo_introspect.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_charmap_encoding.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_claude_md.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_cluster.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_codebuddy.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_confidence.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_corrupt_graph_json.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_cpp_objc_cross_file_calls.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_cpp_preprocess.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_csharp_type_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_dart.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_dedup.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_devin.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_dotnet.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_explain_cli.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_export.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_extract_cli.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_extraction_spec_ids.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_falkordb_integration.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_file_node_id_spec.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_file_slice.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_global_graph.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_google_workspace.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_hypergraph.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_id_normalization_contract.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_import_extension_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_incremental.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_indirect_dispatch_assign_return.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_indirect_dispatch_getattr.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_install.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_install_references.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_install_roundtrip.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_install_strings.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_install_upgrade.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_java_type_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_js_import_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_label_retry.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_labeling.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_language_resolvers.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_llm_backends.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_manifest_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_mcp_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_minhash.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_multigraph_compat.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_multigraph_diagnostics.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_obsidian_filename_cap.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_office_limits.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_ollama.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_openai_custom_endpoint.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_pascal.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_path_cli.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_paths.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_pg_introspect.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_pipeline.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_provider_registry.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_prs.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_python_import_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_query_cli.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_querylog.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_rationale.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_read_hook.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_reflect.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_report.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_scip_ingest.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_security.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_semantic_cleanup.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_semantic_similarity.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_skill_version_warning.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_skillgen.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_swift_import_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_symbol_resolution.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_terraform.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_transcribe.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_ts_inheritance.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_validate.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_vue_extraction.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_wheel_packaging.py +0 -0
- {graphifyy-0.9.4 → graphifyy-0.9.6}/tests/test_wiki.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graphifyy
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.6
|
|
4
4
|
Summary: AI coding assistant skill (Claude Code, CodeBuddy, Codex, OpenCode, Kilo Code, Cursor, Gemini CLI, Aider, OpenClaw, Factory Droid, Trae, Hermes, Kiro, Pi, Devin CLI, Google Antigravity) - turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -151,7 +151,7 @@ Dynamic: license-file
|
|
|
151
151
|
<a href="https://pypi.org/project/graphifyy/"><img src="https://img.shields.io/pypi/v/graphifyy" alt="PyPI"/></a>
|
|
152
152
|
<a href="https://pepy.tech/project/graphifyy"><img src="https://img.shields.io/pepy/dt/graphifyy?color=blue&label=downloads" alt="Downloads"/></a>
|
|
153
153
|
<a href="https://github.com/sponsors/safishamsi"><img src="https://img.shields.io/badge/sponsor-safishamsi-ea4aaa?logo=github-sponsors" alt="Sponsor"/></a>
|
|
154
|
-
<a href="https://www.linkedin.com/
|
|
154
|
+
<a href="https://www.linkedin.com/company/graphify-labs"><img src="https://img.shields.io/badge/LinkedIn-Graphify%20Labs-0077B5?logo=linkedin" alt="LinkedIn"/></a>
|
|
155
155
|
<a href="https://x.com/graphifyy"><img src="https://img.shields.io/badge/X-graphifyy-000000?logo=x&logoColor=white" alt="X"/></a>
|
|
156
156
|
</p>
|
|
157
157
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<a href="https://pypi.org/project/graphifyy/"><img src="https://img.shields.io/pypi/v/graphifyy" alt="PyPI"/></a>
|
|
15
15
|
<a href="https://pepy.tech/project/graphifyy"><img src="https://img.shields.io/pepy/dt/graphifyy?color=blue&label=downloads" alt="Downloads"/></a>
|
|
16
16
|
<a href="https://github.com/sponsors/safishamsi"><img src="https://img.shields.io/badge/sponsor-safishamsi-ea4aaa?logo=github-sponsors" alt="Sponsor"/></a>
|
|
17
|
-
<a href="https://www.linkedin.com/
|
|
17
|
+
<a href="https://www.linkedin.com/company/graphify-labs"><img src="https://img.shields.io/badge/LinkedIn-Graphify%20Labs-0077B5?logo=linkedin" alt="LinkedIn"/></a>
|
|
18
18
|
<a href="https://x.com/graphifyy"><img src="https://img.shields.io/badge/X-graphifyy-000000?logo=x&logoColor=white" alt="X"/></a>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
@@ -3550,10 +3550,59 @@ def main() -> None:
|
|
|
3550
3550
|
except Exception:
|
|
3551
3551
|
existing_labels = {}
|
|
3552
3552
|
if labels_path.exists() and not force_relabel:
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3553
|
+
# Reuse saved labels, but don't blindly trust them: the graph may have
|
|
3554
|
+
# been re-scoped/re-clustered since labeling, in which case a cid now
|
|
3555
|
+
# covers a DIFFERENT community and its old (LLM) name is wrong (#label-stale).
|
|
3556
|
+
# Validate each community against the membership signature saved beside the
|
|
3557
|
+
# labels; any community that changed (or has no saved label) is renamed by
|
|
3558
|
+
# its current hub — deterministic and correct-by-construction — and the user
|
|
3559
|
+
# is told to `graphify label` for fresh LLM names. Unchanged communities keep
|
|
3560
|
+
# their saved label. When no signature sidecar exists (labels predate this),
|
|
3561
|
+
# fall back to hub-filling only the communities missing a label.
|
|
3562
|
+
from graphify.cluster import community_member_sigs, label_communities_by_hub
|
|
3563
|
+
sig_path = labels_path.parent / (labels_path.name + ".sig")
|
|
3564
|
+
saved_sigs: dict[int, str] = {}
|
|
3565
|
+
if sig_path.exists():
|
|
3566
|
+
try:
|
|
3567
|
+
saved_sigs = {
|
|
3568
|
+
int(k): v for k, v in
|
|
3569
|
+
json.loads(sig_path.read_text(encoding="utf-8")).items()
|
|
3570
|
+
if isinstance(v, str)
|
|
3571
|
+
}
|
|
3572
|
+
except Exception:
|
|
3573
|
+
saved_sigs = {}
|
|
3574
|
+
cur_sigs = community_member_sigs(communities)
|
|
3575
|
+
count_mismatch = len(existing_labels) != len(communities)
|
|
3576
|
+
labels = {}
|
|
3577
|
+
hub_labels: dict[int, str] | None = None
|
|
3578
|
+
changed = 0
|
|
3579
|
+
for cid in communities:
|
|
3580
|
+
have_label = cid in existing_labels
|
|
3581
|
+
if saved_sigs:
|
|
3582
|
+
# Precise: the membership signature tells us if this exact
|
|
3583
|
+
# community changed since it was labeled.
|
|
3584
|
+
fresh = have_label and saved_sigs.get(cid) == cur_sigs.get(cid)
|
|
3585
|
+
else:
|
|
3586
|
+
# No signature sidecar (labels predate it). A differing community
|
|
3587
|
+
# COUNT means the labels describe a different clustering, so a cid's
|
|
3588
|
+
# old label can't be trusted; equal count is the best "same" signal.
|
|
3589
|
+
fresh = have_label and not count_mismatch
|
|
3590
|
+
if fresh:
|
|
3591
|
+
labels[cid] = existing_labels[cid]
|
|
3592
|
+
else:
|
|
3593
|
+
if hub_labels is None:
|
|
3594
|
+
hub_labels = label_communities_by_hub(G, communities)
|
|
3595
|
+
labels[cid] = hub_labels[cid]
|
|
3596
|
+
if have_label:
|
|
3597
|
+
changed += 1
|
|
3598
|
+
if changed:
|
|
3599
|
+
print(
|
|
3600
|
+
f"[graphify] community set changed since labeling "
|
|
3601
|
+
f"({len(existing_labels)} saved labels, {len(communities)} communities now; "
|
|
3602
|
+
f"renamed {changed} community(ies) by their hub). "
|
|
3603
|
+
f"Run `graphify label` to refresh names with the LLM.",
|
|
3604
|
+
file=sys.stderr,
|
|
3605
|
+
)
|
|
3557
3606
|
elif no_label and not force_relabel:
|
|
3558
3607
|
labels = {cid: f"Community {cid}" for cid in communities}
|
|
3559
3608
|
else:
|
|
@@ -3606,8 +3655,24 @@ def main() -> None:
|
|
|
3606
3655
|
stages.mark("report")
|
|
3607
3656
|
from graphify.export import backup_if_protected as _backup
|
|
3608
3657
|
_backup(out)
|
|
3658
|
+
analysis = {
|
|
3659
|
+
"communities": {str(k): v for k, v in communities.items()},
|
|
3660
|
+
"cohesion": {str(k): v for k, v in cohesion.items()},
|
|
3661
|
+
"gods": gods,
|
|
3662
|
+
"surprises": surprises,
|
|
3663
|
+
"questions": questions,
|
|
3664
|
+
}
|
|
3665
|
+
(out / ".graphify_analysis.json").write_text(
|
|
3666
|
+
json.dumps(analysis, indent=2, ensure_ascii=False),
|
|
3667
|
+
encoding="utf-8",
|
|
3668
|
+
)
|
|
3609
3669
|
to_json(G, communities, str(out / "graph.json"), community_labels=labels)
|
|
3610
3670
|
labels_path.write_text(json.dumps({str(k): v for k, v in labels.items()}, ensure_ascii=False), encoding="utf-8")
|
|
3671
|
+
# Membership signatures beside the labels so a later cluster-only can detect
|
|
3672
|
+
# which communities changed and avoid reusing a stale label (see reuse above).
|
|
3673
|
+
from graphify.cluster import community_member_sigs as _cms
|
|
3674
|
+
(labels_path.parent / (labels_path.name + ".sig")).write_text(
|
|
3675
|
+
json.dumps({str(k): v for k, v in _cms(communities).items()}), encoding="utf-8")
|
|
3611
3676
|
|
|
3612
3677
|
# Mirror watch.py pattern: gate to_html so core outputs (graph.json +
|
|
3613
3678
|
# GRAPH_REPORT.md) always land. Honor --no-viz explicitly; otherwise
|
|
@@ -3858,7 +3923,14 @@ def main() -> None:
|
|
|
3858
3923
|
# may be a MultiGraph and another a Graph. Normalise everything to Graph
|
|
3859
3924
|
# (the graphify default) by converting MultiGraphs with nx.Graph().
|
|
3860
3925
|
def _to_simple(g: "_nx.Graph") -> "_nx.Graph":
|
|
3861
|
-
|
|
3926
|
+
# nx.compose requires every graph to be the same type. Inputs may
|
|
3927
|
+
# disagree on BOTH axes — directed vs undirected, and multi vs simple
|
|
3928
|
+
# — because per-repo graph.json files are written by different extract
|
|
3929
|
+
# paths at different times. Normalise everything to a plain undirected
|
|
3930
|
+
# Graph (the merged cross-repo view is undirected anyway), which covers
|
|
3931
|
+
# DiGraph / MultiGraph / MultiDiGraph. Without this a directed input
|
|
3932
|
+
# crashed compose with "All graphs must be directed or undirected" (#1606).
|
|
3933
|
+
if type(g) is not _nx.Graph:
|
|
3862
3934
|
return _nx.Graph(g)
|
|
3863
3935
|
return g
|
|
3864
3936
|
merged = _nx.Graph()
|
|
@@ -23,7 +23,7 @@ _BUILTIN_NOISE_LABELS = frozenset({
|
|
|
23
23
|
# Language families — extensions sharing a runtime can legitimately call each other
|
|
24
24
|
_LANG_FAMILY: dict[str, str] = {
|
|
25
25
|
**{e: "python" for e in (".py", ".pyw")},
|
|
26
|
-
**{e: "js" for e in (".js", ".jsx", ".mjs", ".ejs", ".ts", ".tsx", ".vue", ".svelte")},
|
|
26
|
+
**{e: "js" for e in (".js", ".jsx", ".mjs", ".ejs", ".ts", ".tsx", ".mts", ".cts", ".vue", ".svelte")},
|
|
27
27
|
**{e: "go" for e in (".go",)},
|
|
28
28
|
**{e: "rust" for e in (".rs",)},
|
|
29
29
|
**{e: "jvm" for e in (".java", ".kt", ".kts", ".scala")},
|
|
@@ -258,6 +258,11 @@ def _semantic_id_remap(nodes: list, root: str | None) -> dict:
|
|
|
258
258
|
rel = Path(sf_norm)
|
|
259
259
|
if rel.is_absolute():
|
|
260
260
|
continue # can't relativize (no/failed root) — leave id untouched
|
|
261
|
+
if not rel.name:
|
|
262
|
+
# source_file equals the scan root, so _norm_source_file relativized it
|
|
263
|
+
# to Path('.') — a project-level node with no per-file identity to remap.
|
|
264
|
+
# Leave its id untouched (and avoid _file_stem's empty-name crash, #1618).
|
|
265
|
+
continue
|
|
261
266
|
new_stem = make_id(_file_stem(rel))
|
|
262
267
|
if not new_stem:
|
|
263
268
|
continue
|
|
@@ -305,6 +310,8 @@ def graph_has_legacy_ids(nodes: list, root: str | Path | None = None, sample: in
|
|
|
305
310
|
rel = Path(_norm_source_file(str(sf), _r) or str(sf))
|
|
306
311
|
if rel.is_absolute():
|
|
307
312
|
continue
|
|
313
|
+
if not rel.name:
|
|
314
|
+
continue # source_file == scan root -> Path('.'), no file stem (#1618)
|
|
308
315
|
new_stem = make_id(_file_stem(rel))
|
|
309
316
|
if not new_stem:
|
|
310
317
|
continue
|
|
@@ -577,7 +584,7 @@ def build_from_json(extraction: dict, *, directed: bool = False, root: str | Pat
|
|
|
577
584
|
_LANG_FAMILY: dict[str, str] = {
|
|
578
585
|
".py": "py", ".pyi": "py",
|
|
579
586
|
".js": "js", ".mjs": "js", ".cjs": "js", ".jsx": "js",
|
|
580
|
-
".ts": "js", ".tsx": "js",
|
|
587
|
+
".ts": "js", ".tsx": "js", ".mts": "js", ".cts": "js",
|
|
581
588
|
".go": "go", ".rs": "rs",
|
|
582
589
|
".java": "jvm", ".kt": "jvm", ".scala": "jvm", ".groovy": "jvm",
|
|
583
590
|
# C, C++, and ObjC interoperate within one compilation unit: a method
|
|
@@ -110,6 +110,27 @@ def label_communities_by_hub(
|
|
|
110
110
|
return labels
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
def community_member_sigs(communities: dict[int, list[str]]) -> dict[int, str]:
|
|
114
|
+
"""Per-community membership fingerprints: ``{cid: sha256(sorted member ids)}``.
|
|
115
|
+
|
|
116
|
+
Persisted next to ``.graphify_labels.json`` so a later ``cluster-only`` can tell
|
|
117
|
+
which communities actually changed since labeling. A cid whose members no longer
|
|
118
|
+
hash the same is a different community — reusing its old (LLM) label there is the
|
|
119
|
+
"stale label after re-scoping" bug this guards against. Deterministic; independent
|
|
120
|
+
of cid index, node order, and machine.
|
|
121
|
+
"""
|
|
122
|
+
import hashlib
|
|
123
|
+
|
|
124
|
+
sigs: dict[int, str] = {}
|
|
125
|
+
for cid, members in communities.items():
|
|
126
|
+
h = hashlib.sha256()
|
|
127
|
+
for nid in sorted(str(n) for n in members):
|
|
128
|
+
h.update(nid.encode("utf-8", "replace"))
|
|
129
|
+
h.update(b"\x00")
|
|
130
|
+
sigs[cid] = h.hexdigest()[:16]
|
|
131
|
+
return sigs
|
|
132
|
+
|
|
133
|
+
|
|
113
134
|
def cluster(
|
|
114
135
|
G: nx.Graph,
|
|
115
136
|
resolution: float = 1.0,
|
|
@@ -27,7 +27,7 @@ class FileType(str, Enum):
|
|
|
27
27
|
|
|
28
28
|
_MANIFEST_PATH = str(out_path("manifest.json"))
|
|
29
29
|
|
|
30
|
-
CODE_EXTENSIONS = {'.py', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.ejs', '.ets', '.go', '.rs', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.cu', '.cuh', '.metal', '.rb', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.psm1', '.psd1', '.ex', '.exs', '.m', '.mm', '.jl', '.vue', '.svelte', '.astro', '.dart', '.v', '.sv', '.svh', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08', '.pas', '.pp', '.dpr', '.dpk', '.lpr', '.inc', '.dfm', '.lfm', '.lpk', '.sh', '.bash', '.json', '.tf', '.tfvars', '.hcl', '.dm', '.dme', '.dmi', '.dmm', '.dmf', '.sln', '.slnx', '.csproj', '.fsproj', '.vbproj', '.xaml', '.razor', '.cshtml', '.cls', '.trigger'}
|
|
30
|
+
CODE_EXTENSIONS = {'.py', '.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.ejs', '.ets', '.go', '.rs', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.cu', '.cuh', '.metal', '.rb', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.psm1', '.psd1', '.ex', '.exs', '.m', '.mm', '.jl', '.vue', '.svelte', '.astro', '.dart', '.v', '.sv', '.svh', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08', '.pas', '.pp', '.dpr', '.dpk', '.lpr', '.inc', '.dfm', '.lfm', '.lpk', '.sh', '.bash', '.json', '.tf', '.tfvars', '.hcl', '.dm', '.dme', '.dmi', '.dmm', '.dmf', '.sln', '.slnx', '.csproj', '.fsproj', '.vbproj', '.xaml', '.razor', '.cshtml', '.cls', '.trigger'}
|
|
31
31
|
DOC_EXTENSIONS = {'.md', '.mdx', '.qmd', '.txt', '.rst', '.html', '.yaml', '.yml'}
|
|
32
32
|
PAPER_EXTENSIONS = {'.pdf'}
|
|
33
33
|
IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'}
|
|
@@ -991,14 +991,11 @@ def _could_contain_included_path(path: Path, root: Path, patterns: list[tuple[Pa
|
|
|
991
991
|
|
|
992
992
|
|
|
993
993
|
def _auto_follow_symlinks(root: Path) -> bool:
|
|
994
|
-
"""
|
|
994
|
+
"""Return whether ``root`` has any direct symlinked child.
|
|
995
995
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
Override is always possible by passing an explicit ``follow_symlinks=True``
|
|
1001
|
-
or ``follow_symlinks=False`` to :func:`detect` / :func:`detect_incremental`.
|
|
996
|
+
Kept for callers that import the private helper, but detection no longer
|
|
997
|
+
enables symlink following automatically. Following symlinks is now an
|
|
998
|
+
explicit opt-in, and out-of-root symlink targets are never indexed.
|
|
1002
999
|
"""
|
|
1003
1000
|
try:
|
|
1004
1001
|
for p in root.iterdir():
|
|
@@ -1009,10 +1006,19 @@ def _auto_follow_symlinks(root: Path) -> bool:
|
|
|
1009
1006
|
return False
|
|
1010
1007
|
|
|
1011
1008
|
|
|
1009
|
+
def _resolves_under_root(path: Path, root: Path) -> bool:
|
|
1010
|
+
"""True when ``path`` resolves to a target inside ``root``."""
|
|
1011
|
+
try:
|
|
1012
|
+
path.resolve().relative_to(root.resolve())
|
|
1013
|
+
except (OSError, RuntimeError, ValueError):
|
|
1014
|
+
return False
|
|
1015
|
+
return True
|
|
1016
|
+
|
|
1017
|
+
|
|
1012
1018
|
def detect(root: Path, *, follow_symlinks: bool | None = None, google_workspace: bool | None = None, extra_excludes: list[str] | None = None) -> dict:
|
|
1013
1019
|
root = root.resolve()
|
|
1014
1020
|
if follow_symlinks is None:
|
|
1015
|
-
follow_symlinks =
|
|
1021
|
+
follow_symlinks = False
|
|
1016
1022
|
google_workspace = google_workspace_enabled() if google_workspace is None else google_workspace
|
|
1017
1023
|
files: dict[FileType, list[str]] = {
|
|
1018
1024
|
FileType.CODE: [],
|
|
@@ -1072,6 +1078,15 @@ def detect(root: Path, *, follow_symlinks: bool | None = None, google_workspace:
|
|
|
1072
1078
|
if not _is_noise_dir(d, dp)
|
|
1073
1079
|
and not _is_ignored(dp / d, root, ignore_patterns, _cache=ignore_cache)
|
|
1074
1080
|
]
|
|
1081
|
+
if follow_symlinks:
|
|
1082
|
+
safe_dirs: list[str] = []
|
|
1083
|
+
for d in dirnames:
|
|
1084
|
+
child = dp / d
|
|
1085
|
+
if child.is_symlink() and not _resolves_under_root(child, root):
|
|
1086
|
+
skipped_sensitive.append(str(child) + " [symlink target outside scan root]")
|
|
1087
|
+
continue
|
|
1088
|
+
safe_dirs.append(d)
|
|
1089
|
+
dirnames[:] = safe_dirs
|
|
1075
1090
|
for fname in filenames:
|
|
1076
1091
|
if fname in _SKIP_FILES:
|
|
1077
1092
|
continue
|
|
@@ -1093,6 +1108,9 @@ def detect(root: Path, *, follow_symlinks: bool | None = None, google_workspace:
|
|
|
1093
1108
|
continue
|
|
1094
1109
|
if not in_memory and _is_ignored(p, root, ignore_patterns, _cache=ignore_cache):
|
|
1095
1110
|
continue
|
|
1111
|
+
if not _resolves_under_root(p, root):
|
|
1112
|
+
skipped_sensitive.append(str(p) + " [symlink target outside scan root]")
|
|
1113
|
+
continue
|
|
1096
1114
|
if _is_sensitive(p):
|
|
1097
1115
|
skipped_sensitive.append(str(p))
|
|
1098
1116
|
continue
|
|
@@ -1363,11 +1381,10 @@ def detect_incremental(
|
|
|
1363
1381
|
Backwards compatible with legacy manifests storing plain float mtime values
|
|
1364
1382
|
or {mtime, hash} dicts (treated as ast_hash only; semantic_hash = miss).
|
|
1365
1383
|
|
|
1366
|
-
The ``follow_symlinks`` flag is forwarded to :func:`detect` so
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
contains at least one direct symlinked child, ``False`` otherwise.
|
|
1384
|
+
The ``follow_symlinks`` flag is forwarded to :func:`detect` so in-root
|
|
1385
|
+
symlinked sub-trees are scanned consistently between full and incremental
|
|
1386
|
+
runs. ``None`` (default) does not follow symlinked directories; callers must
|
|
1387
|
+
opt in explicitly, and resolved targets outside the scan root are skipped.
|
|
1371
1388
|
"""
|
|
1372
1389
|
full = detect(root, follow_symlinks=follow_symlinks, google_workspace=google_workspace, extra_excludes=extra_excludes)
|
|
1373
1390
|
# Pass ``root`` so a manifest written with relative keys (post-#777) is
|
|
@@ -1278,7 +1278,10 @@ def to_canvas(
|
|
|
1278
1278
|
group_sizes: dict[int, tuple[int, int]] = {}
|
|
1279
1279
|
group_cols: dict[int, int] = {}
|
|
1280
1280
|
for cid in sorted_cids:
|
|
1281
|
-
members
|
|
1281
|
+
# Skip dangling community members with no backing node / filename, so box
|
|
1282
|
+
# sizing matches the cards actually laid out and `G.nodes[m]` never
|
|
1283
|
+
# KeyErrors below — mirrors the to_obsidian guard (#1236).
|
|
1284
|
+
members = [m for m in communities[cid] if m in G and m in node_filenames]
|
|
1282
1285
|
n = len(members)
|
|
1283
1286
|
inner_cols = max(1, math.ceil(math.sqrt(n)))
|
|
1284
1287
|
w = max(600, 220 * inner_cols)
|
|
@@ -1351,6 +1354,9 @@ def to_canvas(
|
|
|
1351
1354
|
# Node cards inside the group - laid out in the same ceil(sqrt(n))-column
|
|
1352
1355
|
# grid the box was sized for (group_cols[cid]), so cards fill the box.
|
|
1353
1356
|
inner_cols = group_cols[cid]
|
|
1357
|
+
# Same dangling-member guard as the sizing loop and to_obsidian (#1236):
|
|
1358
|
+
# a community id absent from G / node_filenames would KeyError the sort.
|
|
1359
|
+
members = [m for m in members if m in G and m in node_filenames]
|
|
1354
1360
|
sorted_members = sorted(members, key=lambda n: G.nodes[n].get("label", n))
|
|
1355
1361
|
for m_idx, node_id in enumerate(sorted_members):
|
|
1356
1362
|
col = m_idx % inner_cols
|