sessionwiki 2.0.0__tar.gz → 2.0.1__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.
- {sessionwiki-2.0.0/sessionwiki.egg-info → sessionwiki-2.0.1}/PKG-INFO +13 -5
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/README.md +12 -4
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/pyproject.toml +1 -1
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/__init__.py +27 -3
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/cli.py +1 -1
- {sessionwiki-2.0.0 → sessionwiki-2.0.1/sessionwiki.egg-info}/PKG-INFO +13 -5
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki.egg-info/SOURCES.txt +1 -1
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_editorconfig_lychee.py +1 -2
- sessionwiki-2.0.1/tests/test_repo_root_resolution.py +90 -0
- sessionwiki-2.0.0/tests/test_homebrew_tap.py +0 -209
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/LICENSE +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/NOTICE +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/__main__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/_frontmatter.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/_system_pages.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapter_config.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/base.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/claude_code.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/codex_cli.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/chatgpt.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/copilot_chat.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/copilot_cli.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/cursor.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/gemini_cli.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/contrib/obsidian.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/opencode.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/status.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/adapters/zcode.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/audit.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/backlinks.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/build.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/cache.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/candidates.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/categories.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/changelog_timeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/compare.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/completion.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/confidence.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/config.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/config_schedule.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/context_md.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/convert.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/docs_pages.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/doctor.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/exporters.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/freshness.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/graph.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/graphify_bridge.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/ingest_queue.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lifecycle.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/link_checker.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/_helpers.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/claim_verification.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/content_freshness.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/contradiction_detection.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/duplicate_detection.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/entity_consistency.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/frontmatter_completeness.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/frontmatter_count_consistency.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/frontmatter_validity.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/index_sync.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/link_integrity.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/orphan_detection.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/stale_candidates.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/stale_reference_detection.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/summary_accuracy.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/tags_topics_convention.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lint/rules/tools_consistency.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/lock.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/log_reader.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/manifest.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/mcp/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/mcp/__main__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/mcp/server.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/models_page.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/obsidian_output.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/opencode/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/opencode/autosync.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/opencode/export.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/opencode/install.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/pipeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/project_topics.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/py.typed +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/quarantine.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/queue.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/references.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/render/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/render/css.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/render/docs_css.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/render/js.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/schema.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/search_facets.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/search_tree.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/serve.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/session_export.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/skill_installer.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/sync/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/sync/status.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/agent_delegate.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/base.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/cli_helpers.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/estimate.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/ollama.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/openai_compat.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/synth/pipeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/tag_utils.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/tags.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/vault.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/viz_heatmap.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/viz_tokens.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/viz_tools.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/watch.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/zcode/__init__.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/zcode/autosync.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/zcode/export.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki/zcode/install.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki.egg-info/dependency_links.txt +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki.egg-info/entry_points.txt +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki.egg-info/requires.txt +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/sessionwiki.egg-info/top_level.txt +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/setup.cfg +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_activity_timeline_label.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_adapter_config.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_adapter_graduation.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_adapter_is_available_unified.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_adapter_tag.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_adapters.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_agent_badges.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_agent_delegate.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_ai_suggested_tags.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_audit.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_backlinks.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_brand_system_doc.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cache.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_candidates.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_categories.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_changelog_page.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_changelog_timeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_chatgpt_adapter.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_chip_contrast.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_ci_workflow.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cli.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cli_doc_parity.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cli_observability.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cmd_all_parser.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cmd_graph_fallback.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_collision_retry.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_compare.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_completion.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_confidence.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_config_layering.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_context_md.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_convert.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_convert_no_op_perf.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_convert_state_and_coerce.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_converter_metrics.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_copilot_adapters.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_cross_platform_paths.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_css_dark_code_and_sticky_header.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_dashboard.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_default_redaction.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_docker.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_docs_structure.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_doctor.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_edge_cases.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_edge_cases_unit.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_filter_slug_label.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_flat_naming.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_force_counters.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_freshness.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_frontmatter_consolidation.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_frontmatter_shared.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_gap_fixes.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_github_link_rewriter.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graph_context_menu.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graph_session.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graph_site_url.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graph_theme_sync.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graph_top_nav.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graph_viewer.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_graphify_bridge.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_healer_comment.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_highlightjs.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_home_card_date_range.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_ignore.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_ingest_queue_shim.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_is_subagent.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_issue_383_pipeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_lifecycle.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_light_mode_polish.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_lint_perf.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_lint_rules.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_lint_windows_paths.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_log_reader.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_mcp_byte_cap.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_mcp_enhanced.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_mcp_protocol.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_mcp_read_page_allowlist.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_mcp_safety.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_md_cache.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_mobile_hamburger_nav.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_models_page.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_no_phantom_adapters.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_obsidian_docs.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_obsidian_templates.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_ollama_backend.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_openai_compat.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_opencode_adapter.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_opencode_autosync.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_opencode_cli.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_opencode_export.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_opencode_install.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_palette_dialog_a11y.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_palette_indexes.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_parse_jsonl_oserror.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_path_traversal.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_post_review_remediation.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_pr_template.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_project_stubs.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_project_topics.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_quarantine.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_queue.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_raw_immutability.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_reader_api_doc.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_readme_badges.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_reference_coverage.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_references.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_release_pipeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_render_is_subagent.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_render_split.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_schedule_config.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_schema.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_schema_entity_types.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_search_facets.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_search_tree.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_serve_smoke.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_session_description.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_session_export.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_session_ref_stripper.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_sessions_index_no_date_dup.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_setup_guide_doc.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_setup_scripts.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_skill_installer.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_slash_cli_parity.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_slug_fallback.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_state_locking.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_subprocess_paths.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_synth_coalesce.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_synth_config_loading.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_synth_pipeline.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_synthesize_cli_pending.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_synthesize_estimate.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_synthesize_overview_safety.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_tag_utils.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_tags.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_theme_pre_paint.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_tutorial_ux.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_two_way_editing.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_ui_a11y_bundle_473.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_username_autodetect.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_username_redact_paths.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_v02.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_v03.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_v04.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_v1378_remediation.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_vault.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_vault_sync_routing.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_viewport_meta.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_viz_heatmap.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_viz_tokens.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_viz_tools.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_wcag_contrast.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_zcode_adapter.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_zcode_autosync.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_zcode_cli.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_zcode_export.py +0 -0
- {sessionwiki-2.0.0 → sessionwiki-2.0.1}/tests/test_zcode_install.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sessionwiki
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: Searchable, interlinked wiki of your AI coding sessions (Claude Code, Codex CLI, Cursor, Gemini CLI, ZCode, OpenCode, Obsidian), with LLM synthesis and MCP access. Based on llmwiki by Pratiyush.
|
|
5
5
|
Author-email: Igor Lashkevich <3133574+necroz@users.noreply.github.com>
|
|
6
6
|
License: MIT
|
|
@@ -63,7 +63,7 @@ Dynamic: license-file
|
|
|
63
63
|
|
|
64
64
|
[](https://github.com/necroz/sessionwiki/blob/master/LICENSE)
|
|
65
65
|
[](https://www.python.org/)
|
|
66
|
-
[](https://github.com/necroz/sessionwiki/blob/master/CHANGELOG.md)
|
|
67
67
|
[](https://github.com/necroz/sessionwiki/tree/master/tests)
|
|
68
68
|
[](https://github.com/necroz/sessionwiki/actions/workflows/ci.yml)
|
|
69
69
|
[](https://github.com/necroz/sessionwiki/actions/workflows/link-check.yml)
|
|
@@ -137,11 +137,19 @@ cd sessionwiki
|
|
|
137
137
|
|
|
138
138
|
`setup` creates a checkout-local `.venv`, installs the package, scaffolds `raw/`, `wiki/`, `site/`, enables the adapters for the agents it finds and runs `sessionwiki doctor`. The wrapper scripts use the venv automatically; for the CLI, activate it (`source .venv/bin/activate`) or call `.venv/bin/sessionwiki`.
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
Or install the published package — pick one:
|
|
141
141
|
|
|
142
142
|
```bash
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
uv tool install sessionwiki # uv: CLI in its own isolated environment
|
|
144
|
+
uvx sessionwiki --help # uv: run without installing
|
|
145
|
+
pip install sessionwiki # pip, inside a virtualenv
|
|
146
|
+
pip install 'sessionwiki[graph]' # + graphify graph engine (also works with uv tool install)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Docker — serve a site you have built (image `ghcr.io/necroz/sessionwiki`, see [Docker deployment](https://github.com/necroz/sessionwiki/blob/master/docs/deploy/docker.md) for `docker compose` and running CLI commands in the container):
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
docker run --rm -p 8765:8765 -v "$PWD/site:/wiki/site:ro" ghcr.io/necroz/sessionwiki
|
|
145
153
|
```
|
|
146
154
|
|
|
147
155
|
A step-by-step walkthrough with screenshots lives in the [setup guide](https://github.com/necroz/sessionwiki/blob/master/docs/tutorials/setup-guide.md).
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/necroz/sessionwiki/blob/master/LICENSE)
|
|
6
6
|
[](https://www.python.org/)
|
|
7
|
-
[](https://github.com/necroz/sessionwiki/blob/master/CHANGELOG.md)
|
|
8
8
|
[](https://github.com/necroz/sessionwiki/tree/master/tests)
|
|
9
9
|
[](https://github.com/necroz/sessionwiki/actions/workflows/ci.yml)
|
|
10
10
|
[](https://github.com/necroz/sessionwiki/actions/workflows/link-check.yml)
|
|
@@ -78,11 +78,19 @@ cd sessionwiki
|
|
|
78
78
|
|
|
79
79
|
`setup` creates a checkout-local `.venv`, installs the package, scaffolds `raw/`, `wiki/`, `site/`, enables the adapters for the agents it finds and runs `sessionwiki doctor`. The wrapper scripts use the venv automatically; for the CLI, activate it (`source .venv/bin/activate`) or call `.venv/bin/sessionwiki`.
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Or install the published package — pick one:
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
uv tool install sessionwiki # uv: CLI in its own isolated environment
|
|
85
|
+
uvx sessionwiki --help # uv: run without installing
|
|
86
|
+
pip install sessionwiki # pip, inside a virtualenv
|
|
87
|
+
pip install 'sessionwiki[graph]' # + graphify graph engine (also works with uv tool install)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Docker — serve a site you have built (image `ghcr.io/necroz/sessionwiki`, see [Docker deployment](https://github.com/necroz/sessionwiki/blob/master/docs/deploy/docker.md) for `docker compose` and running CLI commands in the container):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
docker run --rm -p 8765:8765 -v "$PWD/site:/wiki/site:ro" ghcr.io/necroz/sessionwiki
|
|
86
94
|
```
|
|
87
95
|
|
|
88
96
|
A step-by-step walkthrough with screenshots lives in the [setup guide](https://github.com/necroz/sessionwiki/blob/master/docs/tutorials/setup-guide.md).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sessionwiki"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.1"
|
|
8
8
|
description = "Searchable, interlinked wiki of your AI coding sessions (Claude Code, Codex CLI, Cursor, Gemini CLI, ZCode, OpenCode, Obsidian), with LLM synthesis and MCP access. Based on llmwiki by Pratiyush."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -15,14 +15,38 @@ Public API:
|
|
|
15
15
|
- sessionwiki.mcp.server.main() — MCP server (stdio)
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
__version__ = "2.0.
|
|
18
|
+
__version__ = "2.0.1"
|
|
19
19
|
__author__ = "Igor Lashkevich" # based on llmwiki by Pratiyush (MIT)
|
|
20
20
|
__license__ = "MIT"
|
|
21
21
|
|
|
22
|
+
import os
|
|
22
23
|
from pathlib import Path
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
def _resolve_root(package_file: "str | Path" = __file__) -> Path:
|
|
27
|
+
"""Directory that holds raw/, wiki/, site/ and the state files.
|
|
28
|
+
|
|
29
|
+
1. ``$SESSIONWIKI_HOME`` (or the legacy ``$LLMWIKI_HOME``) when set.
|
|
30
|
+
2. The source checkout, when the package runs from a clone (``./setup.sh``
|
|
31
|
+
or ``pip install -e``): the parent of ``sessionwiki/`` has
|
|
32
|
+
``pyproject.toml``.
|
|
33
|
+
3. Otherwise — ``pip install`` / ``uv tool install`` / ``uvx`` / Docker,
|
|
34
|
+
where the parent is ``site-packages`` — the current directory.
|
|
35
|
+
"""
|
|
36
|
+
for var in ("SESSIONWIKI_HOME", "LLMWIKI_HOME"):
|
|
37
|
+
value = os.environ.get(var, "").strip()
|
|
38
|
+
if value:
|
|
39
|
+
return Path(value).expanduser().resolve()
|
|
40
|
+
checkout = Path(package_file).resolve().parent.parent
|
|
41
|
+
if (checkout / "pyproject.toml").is_file():
|
|
42
|
+
return checkout
|
|
43
|
+
return Path.cwd().resolve()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Data root (raw/, wiki/, site/, state files). See _resolve_root().
|
|
47
|
+
REPO_ROOT = _resolve_root()
|
|
48
|
+
# The installed package itself — use this, not REPO_ROOT, for files that
|
|
49
|
+
# ship inside the package (templates, prompts, bundled assets).
|
|
26
50
|
PACKAGE_ROOT = Path(__file__).resolve().parent
|
|
27
51
|
|
|
28
52
|
# #arch-m4 (#617): the docstring above promised a "public API" but
|
|
@@ -1111,7 +1111,7 @@ def _add_vault_arg(parser: argparse.ArgumentParser, *, role: str) -> None:
|
|
|
1111
1111
|
def build_parser() -> argparse.ArgumentParser:
|
|
1112
1112
|
p = argparse.ArgumentParser(
|
|
1113
1113
|
prog="sessionwiki",
|
|
1114
|
-
description="
|
|
1114
|
+
description="Searchable, interlinked wiki of your AI coding sessions (Claude Code, Codex CLI, Cursor, Gemini CLI, Copilot, ZCode, OpenCode).",
|
|
1115
1115
|
)
|
|
1116
1116
|
p.add_argument("--version", action="version", version=f"sessionwiki {__version__}")
|
|
1117
1117
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sessionwiki
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: Searchable, interlinked wiki of your AI coding sessions (Claude Code, Codex CLI, Cursor, Gemini CLI, ZCode, OpenCode, Obsidian), with LLM synthesis and MCP access. Based on llmwiki by Pratiyush.
|
|
5
5
|
Author-email: Igor Lashkevich <3133574+necroz@users.noreply.github.com>
|
|
6
6
|
License: MIT
|
|
@@ -63,7 +63,7 @@ Dynamic: license-file
|
|
|
63
63
|
|
|
64
64
|
[](https://github.com/necroz/sessionwiki/blob/master/LICENSE)
|
|
65
65
|
[](https://www.python.org/)
|
|
66
|
-
[](https://github.com/necroz/sessionwiki/blob/master/CHANGELOG.md)
|
|
67
67
|
[](https://github.com/necroz/sessionwiki/tree/master/tests)
|
|
68
68
|
[](https://github.com/necroz/sessionwiki/actions/workflows/ci.yml)
|
|
69
69
|
[](https://github.com/necroz/sessionwiki/actions/workflows/link-check.yml)
|
|
@@ -137,11 +137,19 @@ cd sessionwiki
|
|
|
137
137
|
|
|
138
138
|
`setup` creates a checkout-local `.venv`, installs the package, scaffolds `raw/`, `wiki/`, `site/`, enables the adapters for the agents it finds and runs `sessionwiki doctor`. The wrapper scripts use the venv automatically; for the CLI, activate it (`source .venv/bin/activate`) or call `.venv/bin/sessionwiki`.
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
Or install the published package — pick one:
|
|
141
141
|
|
|
142
142
|
```bash
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
uv tool install sessionwiki # uv: CLI in its own isolated environment
|
|
144
|
+
uvx sessionwiki --help # uv: run without installing
|
|
145
|
+
pip install sessionwiki # pip, inside a virtualenv
|
|
146
|
+
pip install 'sessionwiki[graph]' # + graphify graph engine (also works with uv tool install)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Docker — serve a site you have built (image `ghcr.io/necroz/sessionwiki`, see [Docker deployment](https://github.com/necroz/sessionwiki/blob/master/docs/deploy/docker.md) for `docker compose` and running CLI commands in the container):
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
docker run --rm -p 8765:8765 -v "$PWD/site:/wiki/site:ro" ghcr.io/necroz/sessionwiki
|
|
145
153
|
```
|
|
146
154
|
|
|
147
155
|
A step-by-step walkthrough with screenshots lives in the [setup guide](https://github.com/necroz/sessionwiki/blob/master/docs/tutorials/setup-guide.md).
|
|
@@ -183,7 +183,6 @@ tests/test_graphify_bridge.py
|
|
|
183
183
|
tests/test_healer_comment.py
|
|
184
184
|
tests/test_highlightjs.py
|
|
185
185
|
tests/test_home_card_date_range.py
|
|
186
|
-
tests/test_homebrew_tap.py
|
|
187
186
|
tests/test_ignore.py
|
|
188
187
|
tests/test_ingest_queue_shim.py
|
|
189
188
|
tests/test_is_subagent.py
|
|
@@ -230,6 +229,7 @@ tests/test_references.py
|
|
|
230
229
|
tests/test_release_pipeline.py
|
|
231
230
|
tests/test_render_is_subagent.py
|
|
232
231
|
tests/test_render_split.py
|
|
232
|
+
tests/test_repo_root_resolution.py
|
|
233
233
|
tests/test_schedule_config.py
|
|
234
234
|
tests/test_schema.py
|
|
235
235
|
tests/test_schema_entity_types.py
|
|
@@ -97,10 +97,9 @@ def test_lychee_skips_known_future_urls():
|
|
|
97
97
|
assert "v1\\\\.1" in text or "v1.1" in text
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
def
|
|
100
|
+
def test_lychee_skips_pypi_placeholder():
|
|
101
101
|
text = LYCHEE.read_text(encoding="utf-8")
|
|
102
102
|
assert "pypi" in text
|
|
103
|
-
assert "homebrew-sessionwiki" in text
|
|
104
103
|
|
|
105
104
|
|
|
106
105
|
# ─── workflow ─────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Where sessionwiki keeps raw/, wiki/ and site/.
|
|
2
|
+
|
|
3
|
+
Before 2.0.1 the root was always the parent of the package directory.
|
|
4
|
+
That is right for a git clone, but for `pip install` / `uv tool install`
|
|
5
|
+
/ Docker it is `site-packages`, so `sessionwiki init` scaffolded raw/,
|
|
6
|
+
wiki/ and site/ inside the virtualenv (or failed on a read-only image).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import subprocess
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
from sessionwiki import _resolve_root
|
|
19
|
+
|
|
20
|
+
CHECKOUT = Path(__file__).resolve().parent.parent
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _clear(monkeypatch):
|
|
24
|
+
monkeypatch.delenv("SESSIONWIKI_HOME", raising=False)
|
|
25
|
+
monkeypatch.delenv("LLMWIKI_HOME", raising=False)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_source_checkout_is_the_root(monkeypatch, tmp_path):
|
|
29
|
+
_clear(monkeypatch)
|
|
30
|
+
monkeypatch.chdir(tmp_path)
|
|
31
|
+
pkg = CHECKOUT / "sessionwiki" / "__init__.py"
|
|
32
|
+
assert _resolve_root(pkg) == CHECKOUT
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_installed_package_uses_the_current_directory(monkeypatch, tmp_path):
|
|
36
|
+
_clear(monkeypatch)
|
|
37
|
+
site_packages = tmp_path / "venv" / "lib" / "site-packages"
|
|
38
|
+
pkg = site_packages / "sessionwiki" / "__init__.py"
|
|
39
|
+
pkg.parent.mkdir(parents=True)
|
|
40
|
+
pkg.write_text("", encoding="utf-8")
|
|
41
|
+
work = tmp_path / "work"
|
|
42
|
+
work.mkdir()
|
|
43
|
+
monkeypatch.chdir(work)
|
|
44
|
+
assert _resolve_root(pkg) == work.resolve()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@pytest.mark.parametrize("var", ["SESSIONWIKI_HOME", "LLMWIKI_HOME"])
|
|
48
|
+
def test_environment_variable_wins(monkeypatch, tmp_path, var):
|
|
49
|
+
_clear(monkeypatch)
|
|
50
|
+
home = tmp_path / "my-wiki"
|
|
51
|
+
monkeypatch.setenv(var, str(home))
|
|
52
|
+
assert _resolve_root(CHECKOUT / "sessionwiki" / "__init__.py") == home.resolve()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_sessionwiki_home_beats_legacy_name(monkeypatch, tmp_path):
|
|
56
|
+
monkeypatch.setenv("SESSIONWIKI_HOME", str(tmp_path / "new"))
|
|
57
|
+
monkeypatch.setenv("LLMWIKI_HOME", str(tmp_path / "old"))
|
|
58
|
+
assert _resolve_root(CHECKOUT / "sessionwiki" / "__init__.py") == (tmp_path / "new").resolve()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_blank_environment_variable_is_ignored(monkeypatch, tmp_path):
|
|
62
|
+
_clear(monkeypatch)
|
|
63
|
+
monkeypatch.setenv("SESSIONWIKI_HOME", " ")
|
|
64
|
+
assert _resolve_root(CHECKOUT / "sessionwiki" / "__init__.py") == CHECKOUT
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_init_from_an_installed_copy_writes_into_the_working_directory(tmp_path):
|
|
68
|
+
"""End-to-end: a copy of the package outside any checkout (like
|
|
69
|
+
site-packages) must scaffold into the current directory."""
|
|
70
|
+
site_packages = tmp_path / "site-packages"
|
|
71
|
+
subprocess.run(
|
|
72
|
+
[sys.executable, "-c",
|
|
73
|
+
"import shutil, sys; shutil.copytree(sys.argv[1], sys.argv[2], "
|
|
74
|
+
"ignore=shutil.ignore_patterns('__pycache__'))",
|
|
75
|
+
str(CHECKOUT / "sessionwiki"), str(site_packages / "sessionwiki")],
|
|
76
|
+
check=True,
|
|
77
|
+
)
|
|
78
|
+
work = tmp_path / "work"
|
|
79
|
+
work.mkdir()
|
|
80
|
+
env = {k: v for k, v in os.environ.items() if k not in {"SESSIONWIKI_HOME", "LLMWIKI_HOME"}}
|
|
81
|
+
env["PYTHONPATH"] = str(site_packages)
|
|
82
|
+
env["HOME"] = str(tmp_path / "home")
|
|
83
|
+
proc = subprocess.run(
|
|
84
|
+
[sys.executable, "-m", "sessionwiki", "init"],
|
|
85
|
+
cwd=str(work), env=env, capture_output=True, text=True,
|
|
86
|
+
)
|
|
87
|
+
assert proc.returncode == 0, proc.stderr[-500:]
|
|
88
|
+
assert (work / "raw").is_dir() and (work / "wiki").is_dir()
|
|
89
|
+
assert not (site_packages / "raw").exists()
|
|
90
|
+
assert not (site_packages / "wiki").exists()
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
"""Tests for the Homebrew tap kit (v1.1.0 · #102).
|
|
2
|
-
|
|
3
|
-
The formula gets copied into a separate `homebrew-tap` repo that the
|
|
4
|
-
maintainer owns — we can't reach that from CI. What we CAN test:
|
|
5
|
-
|
|
6
|
-
- The formula in this repo stays syntactically + semantically sound.
|
|
7
|
-
- The bump script is executable and enforces its input contract.
|
|
8
|
-
- The auto-bump workflow stays aligned with the bump script + docs.
|
|
9
|
-
- The setup doc documents every user-facing command it mentions.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from __future__ import annotations
|
|
13
|
-
|
|
14
|
-
import os
|
|
15
|
-
import re
|
|
16
|
-
import subprocess
|
|
17
|
-
from pathlib import Path
|
|
18
|
-
|
|
19
|
-
import pytest
|
|
20
|
-
|
|
21
|
-
from sessionwiki import REPO_ROOT
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
FORMULA = REPO_ROOT / "homebrew" / "sessionwiki.rb"
|
|
25
|
-
BUMP_SCRIPT = REPO_ROOT / "scripts" / "bump-homebrew-formula.sh"
|
|
26
|
-
WORKFLOW = REPO_ROOT / ".github" / "workflows" / "homebrew-bump.yml"
|
|
27
|
-
DOC = REPO_ROOT / "docs" / "deploy" / "homebrew-setup.md"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@pytest.fixture(scope="module")
|
|
31
|
-
def formula() -> str:
|
|
32
|
-
return FORMULA.read_text(encoding="utf-8")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
@pytest.fixture(scope="module")
|
|
36
|
-
def bump_script() -> str:
|
|
37
|
-
return BUMP_SCRIPT.read_text(encoding="utf-8")
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@pytest.fixture(scope="module")
|
|
41
|
-
def workflow() -> str:
|
|
42
|
-
return WORKFLOW.read_text(encoding="utf-8")
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@pytest.fixture(scope="module")
|
|
46
|
-
def doc() -> str:
|
|
47
|
-
return DOC.read_text(encoding="utf-8")
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# ─── Formula shape ────────────────────────────────────────────────────
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def test_formula_class_name_matches_filename(formula: str):
|
|
54
|
-
# Homebrew derives the Ruby class name from the formula's filename.
|
|
55
|
-
# `sessionwiki.rb` → `class Sessionwiki`.
|
|
56
|
-
assert re.search(r"^class Sessionwiki < Formula", formula, re.MULTILINE), (
|
|
57
|
-
"formula class must be `Sessionwiki` (camelcase of the filename)"
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def test_formula_has_required_fields(formula: str):
|
|
62
|
-
for field in ("desc ", "homepage ", "url ", "sha256 ", "license "):
|
|
63
|
-
assert field in formula, f"formula missing `{field.strip()}`"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def test_formula_url_points_at_llm_wiki_release_tarball(formula: str):
|
|
67
|
-
m = re.search(r'^ url "([^"]+)"', formula, re.MULTILINE)
|
|
68
|
-
assert m, "formula has no url line"
|
|
69
|
-
url = m.group(1)
|
|
70
|
-
assert url.startswith(
|
|
71
|
-
"https://github.com/necroz/sessionwiki/archive/refs/tags/v"
|
|
72
|
-
), f"unexpected url {url!r}; bump-homebrew-formula.sh rewrites this"
|
|
73
|
-
assert url.endswith(".tar.gz"), "formula url must be the .tar.gz archive"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def test_formula_sha_is_64_hex_or_placeholder(formula: str):
|
|
77
|
-
m = re.search(r'^ sha256 "([^"]+)"', formula, re.MULTILINE)
|
|
78
|
-
assert m, "formula has no sha256 line"
|
|
79
|
-
sha = m.group(1)
|
|
80
|
-
# Two acceptable states: real 64-hex digest (after bump) or the
|
|
81
|
-
# documented placeholder (before a tag ships).
|
|
82
|
-
assert re.fullmatch(r"[0-9a-f]{64}", sha) or "PLACEHOLDER" in sha, (
|
|
83
|
-
f"sha256 value {sha!r} is neither a 64-hex digest nor the "
|
|
84
|
-
"documented PLACEHOLDER — check the bump script output"
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def test_formula_test_block_runs_sessionwiki_commands(formula: str):
|
|
89
|
-
# Homebrew runs the `test do ... end` block on install. We exercise
|
|
90
|
-
# the subcommands that matter to users — `--version` and `adapters`.
|
|
91
|
-
assert 'system bin/"sessionwiki", "--version"' in formula
|
|
92
|
-
assert 'system bin/"sessionwiki", "adapters"' in formula
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def test_formula_depends_on_python_312(formula: str):
|
|
96
|
-
assert 'depends_on "python@3.12"' in formula
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
# ─── Bump script ──────────────────────────────────────────────────────
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def test_bump_script_is_executable():
|
|
103
|
-
assert BUMP_SCRIPT.is_file()
|
|
104
|
-
assert os.access(BUMP_SCRIPT, os.X_OK), (
|
|
105
|
-
"scripts/bump-homebrew-formula.sh must be executable; "
|
|
106
|
-
"run `chmod +x scripts/bump-homebrew-formula.sh`"
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def test_bump_script_rejects_missing_argument(tmp_path: Path):
|
|
111
|
-
result = subprocess.run(
|
|
112
|
-
[str(BUMP_SCRIPT)],
|
|
113
|
-
capture_output=True, text=True, cwd=str(REPO_ROOT),
|
|
114
|
-
)
|
|
115
|
-
assert result.returncode != 0
|
|
116
|
-
assert "usage" in result.stderr.lower()
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def test_bump_script_rejects_non_semver_tag(tmp_path: Path):
|
|
120
|
-
result = subprocess.run(
|
|
121
|
-
[str(BUMP_SCRIPT), "not-a-version"],
|
|
122
|
-
capture_output=True, text=True, cwd=str(REPO_ROOT),
|
|
123
|
-
)
|
|
124
|
-
assert result.returncode != 0
|
|
125
|
-
assert "semver" in result.stderr.lower()
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def test_bump_script_uses_right_tarball_url(bump_script: str):
|
|
129
|
-
# Must match the URL pattern the formula test guards.
|
|
130
|
-
assert (
|
|
131
|
-
"https://github.com/necroz/sessionwiki/archive/refs/tags/${tag}.tar.gz"
|
|
132
|
-
in bump_script
|
|
133
|
-
)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def test_bump_script_handles_macos_and_linux_sed(bump_script: str):
|
|
137
|
-
# macOS/BSD sed needs `-i ''`, GNU sed needs `-i` without the arg.
|
|
138
|
-
# Both branches must exist so the script runs on devs' machines
|
|
139
|
-
# (macOS) and CI (Linux).
|
|
140
|
-
assert "Darwin" in bump_script
|
|
141
|
-
assert "sed -i ''" in bump_script
|
|
142
|
-
assert re.search(r"sed -i -E", bump_script)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
# ─── Auto-bump workflow ───────────────────────────────────────────────
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def test_workflow_triggers_on_version_tags(workflow: str):
|
|
149
|
-
assert 'tags:' in workflow
|
|
150
|
-
assert '"v*.*.*"' in workflow or "'v*.*.*'" in workflow
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def test_workflow_supports_manual_dispatch(workflow: str):
|
|
154
|
-
assert "workflow_dispatch:" in workflow
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def test_workflow_calls_bump_script(workflow: str):
|
|
158
|
-
assert "scripts/bump-homebrew-formula.sh" in workflow
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
def test_workflow_gracefully_handles_missing_secret(workflow: str):
|
|
162
|
-
# When HOMEBREW_TAP_TOKEN isn't set, the job must still succeed —
|
|
163
|
-
# otherwise every release tag turns the workflow red.
|
|
164
|
-
assert "has_token" in workflow
|
|
165
|
-
assert "HOMEBREW_TAP_TOKEN" in workflow
|
|
166
|
-
# Conditional push step
|
|
167
|
-
assert "if: steps.check_token.outputs.has_token == 'true'" in workflow
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def test_workflow_targets_homebrew_tap_repo(workflow: str):
|
|
171
|
-
assert "necroz/homebrew-tap" in workflow
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
# ─── Setup doc ────────────────────────────────────────────────────────
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def test_doc_covers_tap_repo_creation(doc: str):
|
|
178
|
-
# Must mention the literal repo name and the `homebrew-` prefix rule.
|
|
179
|
-
assert "homebrew-tap" in doc
|
|
180
|
-
# The prefix is load-bearing: Homebrew requires the repo name to
|
|
181
|
-
# start with `homebrew-` for `brew tap` to accept it.
|
|
182
|
-
assert re.search(
|
|
183
|
-
r"start with.*homebrew-|name.*must.*homebrew-|homebrew-.*must",
|
|
184
|
-
doc,
|
|
185
|
-
re.IGNORECASE,
|
|
186
|
-
), "doc should flag that the tap repo name must start with `homebrew-`"
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def test_doc_covers_on_every_release_flow(doc: str):
|
|
190
|
-
assert "On every new release" in doc
|
|
191
|
-
assert "bump-homebrew-formula.sh" in doc
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def test_doc_covers_auto_bump_optional_path(doc: str):
|
|
195
|
-
assert "HOMEBREW_TAP_TOKEN" in doc
|
|
196
|
-
assert "gh secret set" in doc
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
def test_doc_covers_troubleshooting(doc: str):
|
|
200
|
-
assert "Troubleshooting" in doc
|
|
201
|
-
# Three documented failure modes
|
|
202
|
-
for k in ("404", "brew test", "class name"):
|
|
203
|
-
assert k in doc, f"doc missing troubleshooting section for {k!r}"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
def test_doc_cross_links_pypi_sibling(doc: str):
|
|
207
|
-
# Both deploy docs should cross-reference each other so users
|
|
208
|
-
# discover the PyPI path from the Homebrew doc and vice versa.
|
|
209
|
-
assert "docs/deploy/pypi-publishing.md" in doc or "pypi-publishing" in doc
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|