jfox-cli 1.0.0__tar.gz → 1.1.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.
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.claude-plugin/marketplace.json +2 -2
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.gitignore +1 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/AGENTS.md +2 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/CHANGELOG.md +24 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/CLAUDE.md +1 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/PKG-INFO +8 -1
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/README.md +7 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/installation.md +26 -0
- jfox_cli-1.1.1/docs/superpowers/plans/2026-06-17-index-rebuild-backlinks.md +166 -0
- jfox_cli-1.1.1/docs/superpowers/plans/2026-06-18-self-update-command.md +175 -0
- jfox_cli-1.1.1/docs/superpowers/plans/2026-06-21-fragment-capture.md +1412 -0
- jfox_cli-1.1.1/docs/superpowers/specs/2026-06-17-index-rebuild-backlinks-design.md +99 -0
- jfox_cli-1.1.1/docs/superpowers/specs/2026-06-18-archive-soft-delete-design.md +160 -0
- jfox_cli-1.1.1/docs/superpowers/specs/2026-06-18-self-update-command-design.md +149 -0
- jfox_cli-1.1.1/docs/superpowers/specs/2026-06-21-fragment-capture-design.md +147 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/__init__.py +1 -1
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/cli.py +706 -10
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/daemon/server.py +77 -1
- jfox_cli-1.1.1/jfox/fragment/__init__.py +7 -0
- jfox_cli-1.1.1/jfox/fragment/cli.py +82 -0
- jfox_cli-1.1.1/jfox/fragment/detector.py +46 -0
- jfox_cli-1.1.1/jfox/fragment/service.py +96 -0
- jfox_cli-1.1.1/jfox/fragment/store.py +124 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/global_config.py +83 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/models.py +18 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/note.py +76 -2
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/note_index.py +49 -2
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/search_engine.py +164 -56
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/.claude-plugin/plugin.json +3 -2
- jfox_cli-1.1.1/packages/cc-plugin/hooks/fragment-capture.sh +36 -0
- jfox_cli-1.1.1/packages/cc-plugin/hooks/hooks.json +38 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/pyproject.toml +1 -1
- jfox_cli-1.1.1/tests/integration/test_fragment_capture_flow.py +98 -0
- jfox_cli-1.1.1/tests/integration/test_index_rebuild_backlinks.py +207 -0
- jfox_cli-1.1.1/tests/unit/test_archive.py +494 -0
- jfox_cli-1.1.1/tests/unit/test_fragment_cli.py +58 -0
- jfox_cli-1.1.1/tests/unit/test_fragment_config.py +56 -0
- jfox_cli-1.1.1/tests/unit/test_fragment_detector.py +86 -0
- jfox_cli-1.1.1/tests/unit/test_fragment_service.py +115 -0
- jfox_cli-1.1.1/tests/unit/test_fragment_store.py +77 -0
- jfox_cli-1.1.1/tests/unit/test_rebuild_backlinks_impl.py +218 -0
- jfox_cli-1.1.1/tests/unit/test_update.py +660 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/utils/jfox_cli.py +5 -2
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/uv.lock +1 -1
- jfox_cli-1.0.0/.claude/settings.local.json +0 -9
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.claude/skills/ci/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.claude/skills/release/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.claude/skills/release/release_helper.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.githooks/pre-push +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/ISSUE_TEMPLATE/docs_improvement.yml +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/workflows/integration-test.yml +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.github/workflows/publish.yml +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/.python-version +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/DEVELOPMENT_PLAN.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/SESSION.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/SESSION_SUMMARY.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/claude-code-plugin-guide.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-11-bulk-import-bm25-fix.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-11-edit-command.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-11-unify-format-option.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-ci-coverage-optimization.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-edit-content-file.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-fix-index-rebuild-clear.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-fix-index-verify-id-mismatch.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-fix-jfox-health-skill-kb-param.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-index-kb-param.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-lazy-import-perf.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-12-skill-redesign.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-13-add-content-file.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-13-bulk-import-vectorstore-init.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-13-ingest-log-command.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-13-ingest-skill-sync.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-13-suppress-third-party-logging.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-13-sync-skills-with-cli.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-14-sync-docs-daemon-show.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-15-gpu-embedding.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-15-make-daemon-deps-required.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-15-session-summary-confirmation.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-16-fix-windows-daemon-console-window.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-18-daemon-timeout-and-index-rebuild.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-22-release-skill.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-26-fix-daemon-deprecation-warnings.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-27-intranet-model-download.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-28-tag-filtering.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-04-29-daemon-stop-fix.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-03-jfox-check.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-03-list-notes-skip-summary.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-03-log-level-fix.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-04-list-notes-index.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-06-atomic-write.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-09-session-note-type.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-10-jfox-plugin.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-19-fix-last-used-never.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-05-20-modelscope-migration.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-06-02-todo-note-type.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-06-16-kimi-code-auto-summary.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/plans/2026-06-17-using-jfox-skill.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-03-bugfixes-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-12-skill-redesign-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-13-pr-auto-code-review-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-14-show-command-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-15-gpu-embedding-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-15-session-summary-confirmation-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-21-release-skill-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-26-fix-daemon-deprecation-warnings-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-27-intranet-model-download-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-28-tag-filtering-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-29-daemon-stop-fix-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-04-30-jfox-kb-env-var-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-03-jfox-check-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-03-list-notes-skip-summary-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-03-log-level-fix-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-04-list-notes-index-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-06-atomic-write-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-09-jfox-plugin-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-09-session-note-type-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-05-20-modelscope-migration-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-06-02-todo-note-type-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-06-16-kimi-code-auto-summary-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/superpowers/specs/2026-06-17-using-jfox-skill-design.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/docs/troubleshooting.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jessica-jones-static-cable.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/__main__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/__init__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/cli.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/extractor.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/kimi_source.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/ledger.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/loop.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/runner.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/scanner.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/auto_summary/sources.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/bm25_index.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/config.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/daemon/__init__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/daemon/__main__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/daemon/client.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/daemon/process.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/embedding_backend.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/formatters.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/git_extractor.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/graph.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/indexer.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/kb_manager.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/model_downloader.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/performance.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/template.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/template_cli.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/utils.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/jfox/vector_store.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/package.json +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/skills/ingest/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/skills/manage/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/skills/organize/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/skills/search/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/skills/session-summary/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/cc-plugin/skills/using-jfox/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/README.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/kimi.plugin.json +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/skills/jfox-ingest/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/skills/jfox-manage/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/skills/jfox-organize/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/skills/jfox-search/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/skills/jfox-session-summary/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/packages/kimi-plugin/skills/using-jfox/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/pytest.ini +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/run_full_test.ps1 +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/scripts/download-model-intranet.sh +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/README.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/kimi-cli/jfox-common/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/kimi-cli/jfox-ingest/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/kimi-cli/jfox-organize/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/kimi-cli/jfox-search/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/kimi-cli/jfox-session-summary/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-ci/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-common/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-ingest/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-organize/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-release/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-search/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/skills-recommend/pi/jfox-session-summary/SKILL.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/COVERAGE_PLAN.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/MIGRATION.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/TESTS.md +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/conftest.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/integration/__init__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/integration/test_auto_summary_kimi.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/integration/test_backlinks.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/integration/test_model_download.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/integration/test_tag_filter_cli.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/performance/__init__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/performance/test_performance.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_advanced_features.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_cli_format.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_config_set_unit.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_config_unit.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_core_workflow.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_embedding_device.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_hybrid_search.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_integration.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_kb_current.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/test_suggest_links.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/__init__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_atomic_write.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_config_sources.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_defaults.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_extractor.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_ledger.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_runner.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_scanner.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_auto_summary_status.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_bm25_batch.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_check.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_content_file.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_daemon_cli.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_daemon_process.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_edit.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_embedding_local_load.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_format_unify.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_formatters.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_git_extractor.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_global_config.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_index_kb_param.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_indexer_clear_before_rebuild.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_indexer_verify.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_kb_manager.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_kimi_extractor.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_kimi_scanner.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_lazy_import.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_ledger_migration.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_list_notes_skip.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_logging_config.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_model_downloader.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_note_index.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_release_helper.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_runner_multi_source.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_scanner_list.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_session_file_source.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_session_note.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_session_source.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_show.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_system_prompt_sections.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_tag_filter.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_template.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_template_cli.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_use_kb_env_var.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_using_jfox_skill.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/unit/test_vector_store_clear.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/utils/__init__.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/utils/assertions.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/utils/note_generator.py +0 -0
- {jfox_cli-1.0.0 → jfox_cli-1.1.1}/tests/utils/temp_kb.py +0 -0
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "JFox Zettelkasten 知识管理工具的 Claude Code 集成",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.3.0"
|
|
11
11
|
},
|
|
12
12
|
"plugins": [
|
|
13
13
|
{
|
|
14
14
|
"name": "jfox",
|
|
15
15
|
"source": "./packages/cc-plugin",
|
|
16
16
|
"description": "JFox 知识管理 CLI 的 Claude Code 集成——搜索、写入工作流(导入/整理/会话总结)与知识库管理",
|
|
17
|
-
"version": "0.
|
|
17
|
+
"version": "0.3.0",
|
|
18
18
|
"author": { "name": "zhuxixi" },
|
|
19
19
|
"keywords": ["zettelkasten", "knowledge-management"],
|
|
20
20
|
"category": "workflow"
|
|
@@ -46,6 +46,7 @@ jfox/
|
|
|
46
46
|
│ ├── kb_manager.py # 知识库管理器
|
|
47
47
|
│ ├── embedding_backend.py # 嵌入模型后端(支持 daemon 代理)
|
|
48
48
|
│ ├── daemon/ # Embedding 模型 HTTP 守护进程
|
|
49
|
+
│ ├── fragment/ # 碎片采集(Hook → daemon API → SQLite)
|
|
49
50
|
│ ├── vector_store.py # ChromaDB 向量存储
|
|
50
51
|
│ ├── bm25_index.py # BM25 关键词索引
|
|
51
52
|
│ ├── search_engine.py # 混合搜索引擎(RRF 融合)
|
|
@@ -161,6 +162,7 @@ uv run jfox --version
|
|
|
161
162
|
| `note_index.py` | 笔记索引管理(文件名↔ID 映射) |
|
|
162
163
|
| `indexer.py` | 文件监控(watchdog)+ 增量索引 |
|
|
163
164
|
| `daemon/` | Embedding 模型 HTTP 守护进程(server/client/process) |
|
|
165
|
+
| `fragment/` | 碎片采集:detector 分类 + store SQLite + service 编排 |
|
|
164
166
|
|
|
165
167
|
### 笔记类型
|
|
166
168
|
|
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to jfox-cli will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.1.1] - 2026-06-21
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
- Claude Code Hook 碎片采集(#261 Phase 1) (#269)
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
- **update**: 已是最新版本时显示正确提示 (#268)
|
|
12
|
+
|
|
13
|
+
### Changes
|
|
14
|
+
- gitignore .claude/settings.local.json and untrack it (#266)
|
|
15
|
+
|
|
16
|
+
[1.1.1]: https://github.com/zhuxixi/jfox/compare/v1.1.0...v1.1.1
|
|
17
|
+
|
|
18
|
+
## [1.1.0] - 2026-06-21
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
- **cli**: add self-update command (#258)
|
|
22
|
+
- 笔记归档/软删除功能(archive/unarchive) (#260)
|
|
23
|
+
|
|
24
|
+
### Fixes
|
|
25
|
+
- **cli**: jfox index rebuild --backlinks recalculates wiki links and backlinks
|
|
26
|
+
|
|
27
|
+
[1.1.0]: https://github.com/zhuxixi/jfox/compare/v1.0.0...v1.1.0
|
|
28
|
+
|
|
5
29
|
## [1.0.0] - 2026-06-18
|
|
6
30
|
|
|
7
31
|
### Features
|
|
@@ -71,6 +71,7 @@ Notes are Markdown files with YAML frontmatter stored under `~/.zettelkasten/<kb
|
|
|
71
71
|
| `bm25_index.py` | BM25 keyword search index |
|
|
72
72
|
| `embedding_backend.py` | Sentence-transformers embedding backend(支持 daemon 代理) |
|
|
73
73
|
| `daemon/` | Embedding 模型 HTTP 守护进程 (`server.py`/`client.py`/`process.py`),`jfox daemon start/stop/status` |
|
|
74
|
+
| `fragment/` | 碎片采集:detector 分类 + store SQLite(WAL) + service 编排 |
|
|
74
75
|
| `vector_store.py` | ChromaDB vector store for semantic search |
|
|
75
76
|
| `graph.py` | NetworkX knowledge graph from links/backlinks |
|
|
76
77
|
| `template.py` / `template_cli.py` | Jinja2 template system for structured note creation |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jfox-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: JFox - Zettelkasten 知识管理 CLI 工具
|
|
5
5
|
Project-URL: Homepage, https://github.com/zhuxixi/jfox
|
|
6
6
|
Project-URL: Repository, https://github.com/zhuxixi/jfox
|
|
@@ -392,6 +392,13 @@ A session is considered "finished" when its file has not been modified for `idle
|
|
|
392
392
|
|
|
393
393
|
> **Privacy note:** Auto-summary sends session text to Anthropic API via `claude -p` to generate summaries. Only session content is transmitted.
|
|
394
394
|
|
|
395
|
+
### Self-Update
|
|
396
|
+
|
|
397
|
+
| Command | Description |
|
|
398
|
+
|---------|-------------|
|
|
399
|
+
| `jfox update` | Upgrade jfox to the latest version (auto-detects pip/pipx/uv) |
|
|
400
|
+
| `jfox update --json` | JSON output with before/after version info |
|
|
401
|
+
|
|
395
402
|
### Global Options
|
|
396
403
|
|
|
397
404
|
| Option | Description |
|
|
@@ -353,6 +353,13 @@ A session is considered "finished" when its file has not been modified for `idle
|
|
|
353
353
|
|
|
354
354
|
> **Privacy note:** Auto-summary sends session text to Anthropic API via `claude -p` to generate summaries. Only session content is transmitted.
|
|
355
355
|
|
|
356
|
+
### Self-Update
|
|
357
|
+
|
|
358
|
+
| Command | Description |
|
|
359
|
+
|---------|-------------|
|
|
360
|
+
| `jfox update` | Upgrade jfox to the latest version (auto-detects pip/pipx/uv) |
|
|
361
|
+
| `jfox update --json` | JSON output with before/after version info |
|
|
362
|
+
|
|
356
363
|
### Global Options
|
|
357
364
|
|
|
358
365
|
| Option | Description |
|
|
@@ -28,6 +28,32 @@ jfox --version
|
|
|
28
28
|
pip install -e ".[dev]"
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## Upgrade
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Auto-detect installation method and upgrade
|
|
35
|
+
jfox update
|
|
36
|
+
|
|
37
|
+
# JSON output with version info
|
|
38
|
+
jfox update --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `jfox update` fails (e.g. behind a proxy or on an unsupported install method), use the manual command for your install method:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# uv tool users
|
|
45
|
+
uv tool upgrade jfox-cli
|
|
46
|
+
|
|
47
|
+
# pipx users
|
|
48
|
+
pipx upgrade jfox-cli
|
|
49
|
+
|
|
50
|
+
# pip users
|
|
51
|
+
pip install --upgrade jfox-cli
|
|
52
|
+
|
|
53
|
+
# Development mode (git clone + uv sync --extra dev)
|
|
54
|
+
git pull && uv sync --extra dev
|
|
55
|
+
```
|
|
56
|
+
|
|
31
57
|
## Uninstall
|
|
32
58
|
|
|
33
59
|
```bash
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Issue #252: `jfox index rebuild` 重新计算 backlinks Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** 让 `jfox index rebuild` 支持 `--backlinks` 选项,在重建索引时重新解析 wiki links 并计算 backlinks。
|
|
6
|
+
|
|
7
|
+
**Architecture:** 在 `jfox/cli.py` 中新增 `_rebuild_backlinks_impl()` 内部函数,在 `index rebuild` action 中按用户传入的 `--backlinks` 标志调用;函数全量加载笔记、解析 `[[...]]` 链接、解析目标 ID、重新计算并写回变化的笔记。
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python, Typer, pytest
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Task 1: 实现 `_rebuild_backlinks_impl()` 内部函数
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Modify: `jfox/cli.py`(在 `extract_wiki_links` / `find_note_id_by_title_or_id` 附近或 `_add_note_impl` 之后新增函数)
|
|
17
|
+
|
|
18
|
+
- [ ] **Step 1: 编写核心函数**
|
|
19
|
+
|
|
20
|
+
新增函数签名:
|
|
21
|
+
```python
|
|
22
|
+
def _rebuild_backlinks_impl(output_format: str = "table") -> Dict[str, Any]:
|
|
23
|
+
...
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
功能:
|
|
27
|
+
1. 调用 `note.list_notes(limit=10000)` 加载所有笔记
|
|
28
|
+
2. 遍历笔记,调用 `extract_wiki_links(note.content)` 提取链接
|
|
29
|
+
3. 调用 `find_note_id_by_title_or_id(link_text)` 解析目标 ID
|
|
30
|
+
4. 构建 `new_links: Dict[str, List[str]]` 和 `new_backlinks: Dict[str, List[str]]`
|
|
31
|
+
5. 对每个笔记,比较现有 `links`/`backlinks` 与新计算结果
|
|
32
|
+
6. 如有变化,更新 Note 对象并调用 `note.save_note(note, add_to_index=False)`
|
|
33
|
+
7. 返回统计信息:`backlinks_rebuilt`, `backlinks_updated`, `backlinks_total`, `unresolved_links`
|
|
34
|
+
|
|
35
|
+
- [ ] **Step 2: 处理边界情况**
|
|
36
|
+
|
|
37
|
+
- 空知识库:返回 `backlinks_total=0`, `backlinks_updated=0`
|
|
38
|
+
- 未解析链接:收集到 `unresolved_links` 列表中用于警告输出
|
|
39
|
+
- 保存失败:记录 warning,不中断流程
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
### Task 2: 在 `index rebuild` action 中集成 `--backlinks` 选项
|
|
44
|
+
|
|
45
|
+
**Files:**
|
|
46
|
+
- Modify: `jfox/cli.py:index()` 命令参数
|
|
47
|
+
- Modify: `jfox/cli.py` 中 `action == "rebuild"` 分支
|
|
48
|
+
|
|
49
|
+
- [ ] **Step 1: 添加 Typer 选项**
|
|
50
|
+
|
|
51
|
+
在 `index()` 命令中新增:
|
|
52
|
+
```python
|
|
53
|
+
backlinks: bool = typer.Option(False, "--backlinks", "-b", help="重建时重新计算 backlinks"),
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- [ ] **Step 2: 在 rebuild action 中调用**
|
|
57
|
+
|
|
58
|
+
在 `action == "rebuild"` 分支中,BM25 重建完成后:
|
|
59
|
+
```python
|
|
60
|
+
if backlinks:
|
|
61
|
+
bl_result = _rebuild_backlinks_impl(output_format)
|
|
62
|
+
result.update(bl_result)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
- [ ] **Step 3: 更新输出**
|
|
66
|
+
|
|
67
|
+
JSON 输出:合并 `backlinks_rebuilt`, `backlinks_updated`, `backlinks_total`, `unresolved_links`
|
|
68
|
+
Table 输出:增加对应行,显示 `Backlinks rebuilt: X / Y`,以及未解析链接警告
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Task 3: 编写测试
|
|
73
|
+
|
|
74
|
+
**Files:**
|
|
75
|
+
- New: `tests/integration/test_index_rebuild_backlinks.py`
|
|
76
|
+
- New: `tests/unit/test_rebuild_backlinks_impl.py`
|
|
77
|
+
|
|
78
|
+
- [ ] **Step 1: 编写集成测试**
|
|
79
|
+
|
|
80
|
+
`tests/integration/test_index_rebuild_backlinks.py`:
|
|
81
|
+
- 使用 `cli` fixture 初始化临时知识库
|
|
82
|
+
- 创建目标笔记 A 和源笔记 B(B 引用 A)
|
|
83
|
+
- 手动修改 A 的 frontmatter,移除其 `backlinks`
|
|
84
|
+
- 执行 `cli.index("rebuild", "--backlinks")`
|
|
85
|
+
- 验证 `refs A` 的 `backward_links` 包含 B
|
|
86
|
+
- 验证 JSON 输出中的 `backlinks_updated > 0`
|
|
87
|
+
|
|
88
|
+
- [ ] **Step 2: 编写单元测试**
|
|
89
|
+
|
|
90
|
+
`tests/unit/test_rebuild_backlinks_impl.py`:
|
|
91
|
+
- Mock `note.list_notes()` 返回若干笔记对象
|
|
92
|
+
- 调用 `_rebuild_backlinks_impl()`
|
|
93
|
+
- 验证统计信息正确
|
|
94
|
+
- 验证 `save_note` 只在变化时调用
|
|
95
|
+
|
|
96
|
+
- [ ] **Step 3: 验证默认行为不变**
|
|
97
|
+
|
|
98
|
+
集成测试增加:
|
|
99
|
+
- 默认 `jfox index rebuild`(无 `--backlinks`)不应修改任何笔记的 backlinks
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### Task 4: 运行测试与代码检查
|
|
104
|
+
|
|
105
|
+
- [ ] **Step 1: 运行新增单元测试**
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uv run pytest tests/unit/test_rebuild_backlinks_impl.py -v
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- [ ] **Step 2: 运行新增集成测试**
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
uv run pytest tests/integration/test_index_rebuild_backlinks.py -v
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- [ ] **Step 3: 运行快速测试集**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uv run pytest tests/ -m "not embedding and not slow" -q
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- [ ] **Step 4: 代码风格检查**
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
uv run ruff check jfox/cli.py tests/unit/test_rebuild_backlinks_impl.py tests/integration/test_index_rebuild_backlinks.py
|
|
127
|
+
uv run black --check jfox/cli.py tests/unit/test_rebuild_backlinks_impl.py tests/integration/test_index_rebuild_backlinks.py
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### Task 5: 提交与 PR
|
|
133
|
+
|
|
134
|
+
- [ ] **Step 1: 整理提交**
|
|
135
|
+
|
|
136
|
+
使用 Conventional Commits:
|
|
137
|
+
```bash
|
|
138
|
+
git add jfox/cli.py tests/unit/test_rebuild_backlinks_impl.py tests/integration/test_index_rebuild_backlinks.py docs/superpowers/specs/2026-06-17-index-rebuild-backlinks-design.md docs/superpowers/plans/2026-06-17-index-rebuild-backlinks.md
|
|
139
|
+
git commit -m "fix(cli): jfox index rebuild --backlinks recalculates wiki links and backlinks
|
|
140
|
+
|
|
141
|
+
- Add --backlinks/-b option to jfox index rebuild
|
|
142
|
+
- Add _rebuild_backlinks_impl() to parse [[...]] links and recompute backlinks
|
|
143
|
+
- Update output JSON/table with backlinks rebuild stats
|
|
144
|
+
- Add unit and integration tests
|
|
145
|
+
|
|
146
|
+
Closes #252"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- [ ] **Step 2: 推送分支**
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
git push origin fix/252-index-rebuild-backlinks
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- [ ] **Step 3: 创建 PR**
|
|
156
|
+
|
|
157
|
+
PR 标题:`fix(cli): jfox index rebuild --backlinks recalculates wiki links and backlinks`
|
|
158
|
+
PR 描述包含:
|
|
159
|
+
- 问题描述
|
|
160
|
+
- 修改内容
|
|
161
|
+
- 测试说明
|
|
162
|
+
- `Closes #252`
|
|
163
|
+
|
|
164
|
+
- [ ] **Step 4: 等待 CI 通过**
|
|
165
|
+
|
|
166
|
+
在 PR 页面确认 Fast / Core workflow 通过。
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# jfox self-update 命令 Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Add a `jfox update` command that detects the current installation method (dev / uv / pipx / pip) and invokes the appropriate upgrade command, showing before/after version info and providing manual fallback guidance on failure.
|
|
6
|
+
|
|
7
|
+
**Architecture:** A new `update` Typer command in `jfox/cli.py` plus helper functions for install-method detection and upgrade command execution. Detection is path-based with command fallbacks. A unit test file `tests/unit/test_update.py` mocks filesystem paths and subprocess calls.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python 3.10+, Typer, Rich, pytest, unittest.mock.
|
|
10
|
+
|
|
11
|
+
**Spec:** `docs/superpowers/specs/2026-06-18-self-update-command-design.md`
|
|
12
|
+
|
|
13
|
+
**Work context:** Work in the isolated worktree `/home/elling/git-repo/github/jfox-wt-238` on branch `feat/issue-238-self-update` (based off `main`). All paths below are relative to that worktree root.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## File Structure
|
|
18
|
+
|
|
19
|
+
| File | Action | Responsibility |
|
|
20
|
+
|------|--------|----------------|
|
|
21
|
+
| `jfox/cli.py` | **Modify** | Add `_detect_install_method`, `_build_upgrade_command`, `_run_upgrade`, `_update_impl`, and `update` Typer command. |
|
|
22
|
+
| `tests/unit/test_update.py` | **Create** | Unit tests for detection, command selection, JSON output, dev-mode prompt, and failure handling. |
|
|
23
|
+
| `README.md` | **Modify** | Add `jfox update` to the command reference table. |
|
|
24
|
+
| `docs/installation.md` | **Modify** | Add an "Upgrade" section with `jfox update` and manual fallbacks. |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Task 1: Implement install-method detection helpers
|
|
29
|
+
|
|
30
|
+
**Files:** `jfox/cli.py`
|
|
31
|
+
|
|
32
|
+
- [ ] **Step 1: Add `_is_dev_installation` helper**
|
|
33
|
+
|
|
34
|
+
Determine development mode by checking whether `jfox.__file__` resolves to a source tree containing `pyproject.toml` with `project.name == "jfox-cli"` and a `.git` directory, or whether the path indicates an editable install (`.egg-link`).
|
|
35
|
+
|
|
36
|
+
- [ ] **Step 2: Add `_is_uv_tool_installation` helper**
|
|
37
|
+
|
|
38
|
+
Run `uv tool dir` to obtain the uv tools root. Return `True` if `jfox.__file__` is relative to `<uv-tool-dir>/jfox-cli/`. If `uv` is unavailable, fall back to path-segment matching (`uv/tools/jfox-cli/`).
|
|
39
|
+
|
|
40
|
+
- [ ] **Step 3: Add `_is_pipx_installation` helper**
|
|
41
|
+
|
|
42
|
+
Run `pipx environment --value PIPX_HOME` to obtain pipx home. Return `True` if `jfox.__file__` is relative to `<pipx-home>/venvs/jfox-cli/`. If `pipx` is unavailable, fall back to path-segment matching (`pipx/venvs/jfox-cli/`).
|
|
43
|
+
|
|
44
|
+
- [ ] **Step 4: Add `_detect_install_method` helper**
|
|
45
|
+
|
|
46
|
+
Apply the detection order: dev → uv → pipx → pip. Return a string identifier (`"dev"`, `"uv"`, `"pipx"`, `"pip"`).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Task 2: Implement upgrade execution and version comparison
|
|
51
|
+
|
|
52
|
+
**Files:** `jfox/cli.py`
|
|
53
|
+
|
|
54
|
+
- [ ] **Step 1: Add `_build_upgrade_command` helper**
|
|
55
|
+
|
|
56
|
+
Map the detected install method to the concrete command list:
|
|
57
|
+
- `"uv"` → `["uv", "tool", "upgrade", "jfox-cli"]`
|
|
58
|
+
- `"pipx"` → `["pipx", "upgrade", "jfox-cli"]`
|
|
59
|
+
- `"pip"` → `[sys.executable, "-m", "pip", "install", "--upgrade", "jfox-cli"]`
|
|
60
|
+
- `"dev"` → return `None`
|
|
61
|
+
|
|
62
|
+
- [ ] **Step 2: Add `_run_upgrade` helper**
|
|
63
|
+
|
|
64
|
+
Use `subprocess.run(..., check=True, capture_output=True, text=True)` to execute the command. On success return stdout; on `CalledProcessError` raise a custom exception or return an error dict. Surface stderr to the user.
|
|
65
|
+
|
|
66
|
+
- [ ] **Step 3: Add `_get_installed_version` helper**
|
|
67
|
+
|
|
68
|
+
Run `jfox --version` via subprocess and parse the version string. Return `"unknown"` if the call fails.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Task 3: Wire up the `update` Typer command
|
|
73
|
+
|
|
74
|
+
**Files:** `jfox/cli.py`
|
|
75
|
+
|
|
76
|
+
- [ ] **Step 1: Add `_update_impl` internal function**
|
|
77
|
+
|
|
78
|
+
1. Read current `__version__`.
|
|
79
|
+
2. Detect install method.
|
|
80
|
+
3. If dev, return a result dict with `success=True`, `method="dev"`, and an instruction string.
|
|
81
|
+
4. Build and run the upgrade command.
|
|
82
|
+
5. Call `_get_installed_version` for the after version.
|
|
83
|
+
6. Return a result dict: `success`, `method`, `previous_version`, `current_version`, `command`, `output`.
|
|
84
|
+
|
|
85
|
+
- [ ] **Step 2: Add `update` Typer command**
|
|
86
|
+
|
|
87
|
+
Support `--format json/table` and `--json` shortcut. Wrap the implementation in a try/except, print table or JSON output, and exit with code 1 on failure.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Task 4: Add unit tests
|
|
92
|
+
|
|
93
|
+
**Files:** `tests/unit/test_update.py`
|
|
94
|
+
|
|
95
|
+
- [ ] **Step 1: Test dev-mode detection**
|
|
96
|
+
|
|
97
|
+
Mock `jfox.__file__` to a source tree path with `pyproject.toml` and `.git/`. Assert `jfox update` prints the dev-mode instruction and does not invoke subprocess.
|
|
98
|
+
|
|
99
|
+
- [ ] **Step 2: Test uv / pipx / pip command selection**
|
|
100
|
+
|
|
101
|
+
Mock `jfox.__file__` to each tool's typical site-packages path and assert the correct subprocess command is invoked.
|
|
102
|
+
|
|
103
|
+
- [ ] **Step 3: Test JSON output**
|
|
104
|
+
|
|
105
|
+
Run `jfox update --json` and verify the parsed JSON contains expected keys.
|
|
106
|
+
|
|
107
|
+
- [ ] **Step 4: Test upgrade failure handling**
|
|
108
|
+
|
|
109
|
+
Make `subprocess.run` raise `CalledProcessError`. Assert exit code 1 and manual command guidance appears in output/JSON.
|
|
110
|
+
|
|
111
|
+
- [ ] **Step 5: Test version before/after display**
|
|
112
|
+
|
|
113
|
+
Mock `jfox.__version__` and the post-upgrade `jfox --version` subprocess to verify both versions appear.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Task 5: Update documentation
|
|
118
|
+
|
|
119
|
+
**Files:** `README.md`, `docs/installation.md`
|
|
120
|
+
|
|
121
|
+
- [ ] **Step 1: Add `jfox update` to README command table**
|
|
122
|
+
|
|
123
|
+
Place it under a new "Self-update" row or in the most appropriate existing section.
|
|
124
|
+
|
|
125
|
+
- [ ] **Step 2: Add upgrade section to `docs/installation.md`**
|
|
126
|
+
|
|
127
|
+
Document `jfox update` and the manual fallbacks for each install method.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Task 6: Run tests and static checks
|
|
132
|
+
|
|
133
|
+
- [ ] **Step 1: Run the new unit tests**
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
uv run pytest tests/unit/test_update.py -v
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
- [ ] **Step 2: Run fast unit tests**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
uv run pytest tests/unit/ -m "not embedding and not slow" -q
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- [ ] **Step 3: Run ruff lint**
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
uv run ruff check jfox/cli.py tests/unit/test_update.py
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Task 7: Commit and create PR
|
|
154
|
+
|
|
155
|
+
- [ ] **Step 1: Stage and commit changes**
|
|
156
|
+
|
|
157
|
+
Use Conventional Commits:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
git add jfox/cli.py tests/unit/test_update.py README.md docs/installation.md docs/superpowers/
|
|
161
|
+
git commit -m "feat(cli): add self-update command (jfox update)"
|
|
162
|
+
git commit -m "docs(readme): document jfox update command" -- README.md docs/installation.md
|
|
163
|
+
git commit -m "docs(superpowers): add self-update design and plan"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
- [ ] **Step 2: Push branch and create PR**
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
git push -u origin feat/issue-238-self-update
|
|
170
|
+
gh pr create --title "feat(cli): add self-update command" --body "Closes #238" --base main
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
- [ ] **Step 3: Wait for CI**
|
|
174
|
+
|
|
175
|
+
Monitor the PR checks and address any failures.
|