jfox-cli 1.16.0__tar.gz → 1.16.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.16.0 → jfox_cli-1.16.1}/CHANGELOG.md +18 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/CLAUDE.md +12 -5
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/PKG-INFO +1 -1
- jfox_cli-1.16.1/docs/superpowers/plans/2026-09-24-adjacent-backticks-swallow-wiki-links.md +224 -0
- jfox_cli-1.16.1/docs/superpowers/specs/2026-09-24-adjacent-backticks-swallow-wiki-links-design.md +119 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/__init__.py +1 -1
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/note_index.py +14 -8
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/pyproject.toml +1 -1
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_backlinks.py +28 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_wiki_link_resolution.py +50 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/uv.lock +1 -1
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/ci/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release/release_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-all/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-all/release_all_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-cc-plugin/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-cc-plugin/release_cc_plugin_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-kimi-plugin/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-kimi-plugin/release_kimi_plugin_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude-plugin/marketplace.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.githooks/pre-push +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/ISSUE_TEMPLATE/docs_improvement.yml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/workflows/integration-test.yml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.github/workflows/publish.yml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.gitignore +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.markdownlint-cli2.jsonc +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.pi-lens.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/.python-version +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/AGENTS.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/DEVELOPMENT_PLAN.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/README.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/SESSION.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/SESSION_SUMMARY.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/claude-code-plugin-guide.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/cli-descriptions.yaml +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/cli-reference.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/installation.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/json-schemas.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/nightly-test.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/plugin-inventory.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-11-bulk-import-bm25-fix.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-11-edit-command.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-11-unify-format-option.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-ci-coverage-optimization.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-edit-content-file.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-fix-index-rebuild-clear.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-fix-index-verify-id-mismatch.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-fix-jfox-health-skill-kb-param.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-index-kb-param.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-lazy-import-perf.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-12-skill-redesign.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-13-add-content-file.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-13-bulk-import-vectorstore-init.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-13-ingest-log-command.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-13-ingest-skill-sync.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-13-suppress-third-party-logging.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-13-sync-skills-with-cli.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-14-sync-docs-daemon-show.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-15-gpu-embedding.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-15-make-daemon-deps-required.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-15-session-summary-confirmation.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-16-fix-windows-daemon-console-window.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-18-daemon-timeout-and-index-rebuild.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-22-release-skill.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-26-fix-daemon-deprecation-warnings.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-27-intranet-model-download.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-28-tag-filtering.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-04-29-daemon-stop-fix.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-03-jfox-check.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-03-list-notes-skip-summary.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-03-log-level-fix.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-04-list-notes-index.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-06-atomic-write.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-09-session-note-type.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-10-jfox-plugin.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-19-fix-last-used-never.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-05-20-modelscope-migration.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-02-todo-note-type.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-16-kimi-code-auto-summary.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-17-index-rebuild-backlinks.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-17-using-jfox-skill.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-18-self-update-command.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-21-fragment-capture.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-21-gem-synthesis.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-06-25-gem-synth-throttle-ledger.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-08-auto-summary-schedule-window.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-08-candidate-promote.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-12-gem-synth-dedup.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-12-release-cc-plugin-skill.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-12-session-summary-streamline.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-12-show-json.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-17-fix-candidate-dual-h1.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-18-dedup-lifecycle-decouple.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-19-promote-skill-three-modes.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-25-bookshelf.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-25-gem-synth-dedup-incremental-merge.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-26-kb-backup-restore.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-26-promote-skill-clear-reports-rewrite.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-27-release-all.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-28-bookshelf-flat-bundle.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-07-28-nightly-fulltest.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-07-session-to-permanent-cc-kimi.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-11-permanent-note-template.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-12-noteindex-frontmatter-limit-drop.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-15-delete-backlinks-cleanup.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-16-bm25-concurrent-write-race.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-21-index-verify-legacy-filenames.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-21-moc-density-diagnose.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-22-bm25-type-debt-cleanup.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-22-issue-392-cr-leftovers.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-22-jfox-moc-skill.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-22-markdownlint-adoption.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-22-moc-create-update.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-25-moc-create-update-json-shorthand.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-27-issue-436-organize-archive.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-28-cpu-default-model-bge-small-zh.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-29-english-readme-baseline.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-29-issue-383-add-permanent-dedup.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-29-louvain-moc-clustering.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-30-gem-synth-prompt-judgment.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-30-test-config-isolation.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-08-31-deterministic-cli-reference.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-01-ci-docs-drift-gate.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-02-plugin-inventory-enum-checks.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-03-jfox-moc-batch-quality-chapter.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-03-moc-member-management.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-04-chromadb-dim-migration-ndarray.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-05-moc-diagnose-archived-orphan.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-07-bm25-fresh-kb-logging.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-07-pi-prompt-capture.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-09-from-dict-non-dict-guard.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-09-nightly-test-failures.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-10-skill-sync-399-overview-jfox-judge.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-14-json-schema-unify.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-14-lightweight-install.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-14-wiki-link-self-link.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/plans/2026-09-23-h1-strip-normalization.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-03-bugfixes-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-12-skill-redesign-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-13-pr-auto-code-review-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-14-show-command-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-15-gpu-embedding-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-15-session-summary-confirmation-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-21-release-skill-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-26-fix-daemon-deprecation-warnings-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-27-intranet-model-download-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-28-tag-filtering-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-29-daemon-stop-fix-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-04-30-jfox-kb-env-var-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-03-jfox-check-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-03-list-notes-skip-summary-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-03-log-level-fix-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-04-list-notes-index-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-06-atomic-write-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-09-jfox-plugin-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-09-session-note-type-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-05-20-modelscope-migration-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-02-todo-note-type-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-16-kimi-code-auto-summary-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-17-index-rebuild-backlinks-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-17-using-jfox-skill-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-18-archive-soft-delete-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-18-self-update-command-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-21-fragment-capture-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-21-gem-synthesis-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-06-25-gem-synth-throttle-ledger-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-08-candidate-promote-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-12-gem-synth-dedup-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-12-release-cc-plugin-skill-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-12-session-summary-streamline-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-12-show-json-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-18-dedup-lifecycle-decouple-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-19-promote-skill-three-modes-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-25-bookshelf-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-25-gem-synth-dedup-incremental-merge-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-26-kb-backup-restore-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-26-promote-skill-clear-reports-rewrite-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-27-release-all-orchestration-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-28-bookshelf-flat-bundle-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-07-28-nightly-fulltest-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-07-session-to-permanent-cc-kimi-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-11-permanent-note-template-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-12-noteindex-frontmatter-limit-drop-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-15-delete-backlinks-cleanup-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-16-bm25-concurrent-write-race-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-20-bm25-clear-orphan-followup-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-21-index-verify-legacy-filenames-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-21-moc-density-diagnose-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-22-bm25-type-debt-cleanup-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-22-issue-392-cr-leftovers-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-22-jfox-moc-skill-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-22-markdownlint-adoption-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-22-moc-create-update-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-25-moc-create-update-json-shorthand-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-27-issue-436-organize-archive-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-27-redirect-and-delete-guard.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-28-cpu-default-model-bge-small-zh-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-29-english-readme-baseline-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-29-issue-383-add-permanent-dedup-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-29-louvain-moc-clustering-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-30-gem-synth-prompt-judgment-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-30-test-config-isolation-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-08-31-deterministic-cli-reference-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-01-ci-docs-drift-gate-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-02-plugin-inventory-enum-checks-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-03-jfox-moc-batch-quality-chapter-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-03-moc-member-management-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-04-chromadb-dim-migration-ndarray-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-05-moc-diagnose-archived-orphan-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-07-bm25-fresh-kb-logging-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-07-pi-prompt-capture-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-09-from-dict-non-dict-guard-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-09-nightly-test-failures-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-10-lightweight-install-embed-extra-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-10-skill-sync-399-overview-jfox-judge-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-14-json-schema-unify-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-14-wiki-link-self-link-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/superpowers/specs/2026-09-23-h1-strip-normalization-design.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/docs/troubleshooting.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jessica-jones-static-cable.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/__main__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/add_dedup.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/extractor.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/kimi_source.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/ledger.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/loop.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/runner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/scanner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/schedule.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/auto_summary/sources.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/backup/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/backup/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/backup/loop.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/backup/manager.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/backup/schedule.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/bm25_index.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/bookshelf/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/bookshelf/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/bookshelf/meta.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/bookshelf/store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/candidates/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/candidates/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/candidates/service.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/config.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/daemon/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/daemon/__main__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/daemon/client.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/daemon/process.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/daemon/server.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/dedup.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/dedup_lifecycle.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/embedding_backend.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/embedding_migration.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/formatters.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/fragment/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/fragment/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/fragment/internal_sources.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/fragment/service.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/fragment/store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/git_extractor.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/global_config.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/graph.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/indexer.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/kb_manager.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/moc/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/moc/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/moc/cluster.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/moc/draft.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/moc/generate.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/model_downloader.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/models.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/note.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/performance.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/actions.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/grounding.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/judge.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/lifecycle.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/runner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/service.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/prompts/transcript.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/redirect.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/search_engine.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/template.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/template_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/utils.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/jfox/vector_store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/package.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/.claude-plugin/plugin.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/hooks/fragment-capture.sh +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/hooks/hooks.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/bookshelf/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/ingest/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/manage/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/organize/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/promote/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/search/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/session-summary/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/session-to-permanent/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/cc-plugin/skills/using-jfox/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/README.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/kimi.plugin.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-admin/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-auto-summary/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-ingest/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-manage/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-organize/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-promote/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-search/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-session-summary/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-session-to-permanent/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/jfox-template/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/kimi-plugin/skills/using-jfox/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/pi-plugin/README.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/pi-plugin/extensions/jfox-prompt-capture.ts +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/packages/pi-plugin/test/run-tests.ts +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/pytest.ini +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/run_full_test.ps1 +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/LOUVAIN_VERIFY.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/download-model-intranet.sh +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/enum_coverage.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/generate_docs.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/louvain_verify.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/nightly_test.sh +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/nightly_test_helpers.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/plugin_inventory.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/scripts/verify_lightweight_install.sh +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/README.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/kimi-cli/jfox-common/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/kimi-cli/jfox-ingest/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/kimi-cli/jfox-organize/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/kimi-cli/jfox-search/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/kimi-cli/jfox-session-summary/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-bookshelf/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-ci/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-common/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-ingest/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-judge/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-moc/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-organize/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-overview/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-promote/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-release/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-release-all/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-release-cc-plugin/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-release-kimi-plugin/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-search/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-session-summary/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/skills-recommend/pi/jfox-session-to-permanent/SKILL.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/COVERAGE_PLAN.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/MIGRATION.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/TESTS.md +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/conftest.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/fixtures/bulk_import_notes.json +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_auto_summary_kimi.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_candidate_promote_flow.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_cli_reference_generation.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_edit_roundtrip.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_fragment_capture_flow.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_index_rebuild_backlinks.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_links_edit_add.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_moc_member_commands.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_model_download.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_no_embed_degradation.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_plugin_inventory.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/integration/test_tag_filter_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/performance/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/performance/test_performance.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_add_dedup_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_advanced_features.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_cli_format.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_config_set_unit.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_config_unit.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_core_workflow.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_embedding_device.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_hybrid_search.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_integration.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_json_schema_contract.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_kb_current.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/test_suggest_links.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/bookshelf/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/bookshelf/conftest.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/bookshelf/test_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/bookshelf/test_meta.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/bookshelf/test_store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/conftest.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_add_backfill_links.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_add_dedup.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_archive.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_atomic_write.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_config_sources.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_defaults.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_extractor.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_ledger.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_loop.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_runner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_scanner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_schedule.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_auto_summary_status.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_backup.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_bm25_batch.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_bm25_concurrency.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_bm25_fresh_kb_logging.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_candidates_migrated_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_check.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_conftest_mock.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_content_file.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_daemon_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_daemon_process.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_dedup_lifecycle.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_default_model_switch.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_delete_backlink_cleanup.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_delete_guard.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_edit.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_embed_availability.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_embedding_backend_daemon_only.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_embedding_local_load.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_embedding_migration.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_enum_coverage.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_format_unify.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_formatters.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_fragment_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_fragment_config.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_fragment_hook.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_fragment_internal_sources.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_fragment_service.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_fragment_store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_generate_docs.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_git_extractor.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_global_config.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_index_kb_param.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_indexer_clear_before_rebuild.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_indexer_verify.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_json_mode.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_kb_manager.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_kimi_extractor.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_kimi_plugin_skills.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_kimi_scanner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_lazy_import.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_ledger_migration.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_list_notes_skip.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_logging_config.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_cluster.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_create_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_draft.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_generate.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_integration.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_member_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_skill_docs.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_moc_update_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_model_downloader.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_nightly_test_helpers.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_add_config.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_candidate_fields.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_candidate_filename.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_generator.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_index.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_lifecycle_hooks.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_promote.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_type_candidate.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_note_type_structure.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_plugin_inventory.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_actions.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_backfill.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_candidate.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_capture.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_grounding.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_judge.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_retirement.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_runner.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_store.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_prompt_transcript.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_pyproject_embed_extra.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_rebuild_backlinks_impl.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_redirect.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_release_all_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_release_cc_plugin_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_release_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_release_helper_verify.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_release_kimi_plugin_helper.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_runner_multi_source.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_scanner_list.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_search_engine_embed_warning.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_session_file_source.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_session_note.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_session_source.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_show.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_system_prompt_sections.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_tag_filter.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_template.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_template_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_update.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_use_kb_env_var.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_using_jfox_skill.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_vector_store_clear.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_vector_store_dimension_warning.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_vector_store_embed_guard.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/unit/test_vector_store_embeddings.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/utils/__init__.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/utils/assertions.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/utils/jfox_cli.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/utils/note_generator.py +0 -0
- {jfox_cli-1.16.0 → jfox_cli-1.16.1}/tests/utils/temp_kb.py +0 -0
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to jfox-cli will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.16.1] - 2026-09-24
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- **note_index**: 剥离改单遍合并正则——反引号包 HTML 注释不再吞后续 wiki link (#548) (#550)
|
|
10
|
+
|
|
11
|
+
### Changes
|
|
12
|
+
|
|
13
|
+
- **claude.md**: batch refresh — fold in 6 pending auto/claude-md PRs (#520/#524/#527/#532/#540/#545) (#546)
|
|
14
|
+
|
|
15
|
+
[1.16.1]: https://github.com/zhuxixi/jfox/compare/v1.16.0...v1.16.1
|
|
16
|
+
|
|
17
|
+
## [Unreleased]
|
|
18
|
+
|
|
19
|
+
### Fixes
|
|
20
|
+
|
|
21
|
+
- **note_index**: 剥离改单遍合并正则——反引号包 HTML 注释不再吞后续 wiki link (#548) (#550)
|
|
22
|
+
|
|
5
23
|
## [1.16.0] - 2026-09-23
|
|
6
24
|
|
|
7
25
|
### Features
|
|
@@ -62,7 +62,7 @@ Notes are Markdown files with YAML frontmatter stored under `~/.zettelkasten/<kb
|
|
|
62
62
|
|--------|------|
|
|
63
63
|
| `cli.py` | All CLI commands (~4200 lines). Commands follow pattern: `@app.command()` → `_xxx_impl()` helper for reuse |
|
|
64
64
|
| `config.py` | `ZKConfig` + `use_kb()` context manager for multi-KB switching |
|
|
65
|
-
| `global_config.py` | `GlobalConfigManager` managing `~/.zk_config.json` |
|
|
65
|
+
| `global_config.py` | `GlobalConfigManager` managing `~/.zk_config.json`;损坏恢复契约(#481/#526):`from_dict` 各级非 dict 守卫回默认,文件级加载失败先字节级备份 `.corrupt-*` 快照再恢复默认,备份失败则不落盘覆盖原文件 |
|
|
66
66
|
| `kb_manager.py` | Knowledge base lifecycle (create, rename, remove) |
|
|
67
67
|
| `formatters.py` | Output formats: JSON, CSV, YAML, Table, Paths |
|
|
68
68
|
| `git_extractor.py` | Git 仓库数据提取器(ingest 功能) |
|
|
@@ -74,7 +74,7 @@ Notes are Markdown files with YAML frontmatter stored under `~/.zettelkasten/<kb
|
|
|
74
74
|
| `add_dedup.py` | `jfox add` permanent 落库前双通道防重(#383):标题通道(非 archived 同标题、大小写不敏感、不限类型)+ 正文余弦 ≥0.95 通道(复用顶层 `jfox/dedup.py`,`daemon_only=True` 绝不回退本地模型加载、仅 daemon 在跑时启用);闸门自身故障一律放行,非路障 |
|
|
75
75
|
| `search_engine.py` | `HybridSearchEngine` with `SearchMode` enum, RRF fusion |
|
|
76
76
|
| `bm25_index.py` | BM25 keyword search index;写路径 filelock + 原子写 + `write_version` 乐观并发控制,多进程并发写安全(#391/#396) |
|
|
77
|
-
| `embedding_backend.py` | Sentence-transformers embedding backend(支持 daemon 代理);CPU 默认模型 `BAAI/bge-small-zh-v1.5`(512 维,#442),本地模型目录未命中时先走 ModelDownloader 下载链再兜底加载(#374
|
|
77
|
+
| `embedding_backend.py` | Sentence-transformers embedding backend(支持 daemon 代理);CPU 默认模型 `BAAI/bge-small-zh-v1.5`(512 维,#442),本地模型目录未命中时先走 ModelDownloader 下载链再兜底加载(#374);#519 起该包拆入 `[embed]` extra 可选——`is_embedding_service_available()` 探测(本地 `find_spec` 模块级缓存 + daemon 实时检查),缺失时 `load()` 抛 `EmbedDependencyMissingError`(message 含安装提示),`reset_embed_availability_cache()` 为测试后门 |
|
|
78
78
|
| `daemon/` | Embedding 模型 HTTP 守护进程 (`server.py`/`client.py`/`process.py`),`jfox daemon start/stop/status` |
|
|
79
79
|
| `embedding_migration.py` | 全 KB 向量维度不匹配检测(#442):daemon start/restart 时比对各 KB Chroma 集合维度与 daemon 服务维度,发现旧模型建库则交互式逐 KB 提示 rebuild,单 KB 失败不阻断其余 |
|
|
80
80
|
| `fragment/` | 碎片子系统(采集已退役,#498):detector 分类与 `ingest_event` 采集链删除,仅留 store SQLite(WAL) 与历史回溯 CLI `jfox fragments list/show`;旧 `session_fragments` 表保留供 prompts `backfill` 回填 |
|
|
@@ -116,6 +116,8 @@ Notes are Markdown files with YAML frontmatter stored under `~/.zettelkasten/<kb
|
|
|
116
116
|
- **Comments/docs**: Chinese (中文)
|
|
117
117
|
- **README**: 英文 baseline(#461 起重写),改 README 保持英文;其余项目文档/注释仍中文
|
|
118
118
|
- **Adding a CLI command**: Add `@app.command()` in `cli.py`, implement `_xxx_impl()` helper, add `--kb` and `--format json` support(`--json` 简写等价于 `--format json`,全 CLI 统一约定,moc create/update 曾漏补,#425);命令面有任何增删改还须补 `docs/cli-descriptions.yaml` 英文描述并跑 `uv run python scripts/generate_docs.py` 重新生成 `docs/cli-reference.md`,否则 CI lint drift gate 挂(#474/#476)
|
|
119
|
+
- **`--json` 输出 schema 合同**(#502/#531): 全部命令 JSON 输出顶层必有 `success: bool`,失败必有非空 `error` + exit 1,裸数组包成 `{success, items}`(如 prompts/backup list)。权威 schema 参考 `docs/json-schemas.md`(改 JSON 字段须同步更新),合同由 `tests/test_json_schema_contract.py` 锁定
|
|
120
|
+
- **Wiki-link 解析收敛**: edit/add/rebuild 三路径统一走 `cli.py` 的 `resolve_wiki_links()`(剥离 code fence/inline code/HTML 注释 → 三级匹配解析 → 自链过滤 → 去重,找不到的进 unresolved),改链接解析规则只改这一处(#511/#530)
|
|
119
121
|
- **Adding a search mode**: Add to `SearchMode` enum in `search_engine.py`, implement in `HybridSearchEngine.search()`, update CLI `--mode` help text
|
|
120
122
|
- **Adding a daemon-scheduled loop**: 镜像 `auto_summary/`(与 backup 同构)——`loop.py`(`_tick_once` + async `X_loop(stop_event)`)+ `daemon/server.py` lifespan 内 `_maybe_start/stop_X` 接线 + `GlobalConfigManager` opt-in(每 tick `reload()` 即时生效);任何写类 loop 的 `_tick_once` 开头须 check `BackupCoordinator.is_running()` 跳过写,避免备份期间 ChromaDB 并发写
|
|
121
123
|
- **Modifying data models**: Update `Note` class in `models.py`, update `to_markdown()`/`from_markdown()`, consider backward compat
|
|
@@ -123,14 +125,17 @@ Notes are Markdown files with YAML frontmatter stored under `~/.zettelkasten/<kb
|
|
|
123
125
|
- **笔记生命周期事件**: `note.py` 只广播 `post_delete`/`post_archive`/`post_promote`/`post_reject`(`register_lifecycle_hook` + `_dispatch`),绝不 import 特性层;特性层订阅做副作用(如 `dedup_lifecycle.py` 同步 dedup 表、`prompts/lifecycle.py` 同步 judgment)。`register` 在 `jfox/__init__.py` 接线,任何 `import jfox.*` 即订阅就位,库式调用方零成本
|
|
124
126
|
- **源笔记清理统一 archive**: skill 整理/提炼后清理源笔记用 `jfox archive`(软删除,`jfox unarchive` 可回滚误判),不用 `delete --force` 硬删(#436)
|
|
125
127
|
- **`jfox add` permanent 防重**(#383/#483): 默认开启,标题或正文余弦 ≥0.95 命中即拒绝创建(exit 1,JSON 输出 `skipped: "duplicate"`),`--force` 跳过(迁移/回填用);开关与阈值在 `~/.zk_config.json` 的 `note_add` 节(`NoteAddConfig`);embedding 通道仅 daemon 在跑时生效,落库后回灌 dedup 表供后续 add 查重
|
|
128
|
+
- **`--content-file` 输入规范化**(#541/#542): `jfox add`/`edit` 的 `--content-file`(文件路径与 stdin `-` 同一语义)统一剥 BOM/frontmatter 后**无条件剥首个 H1**(与读盘侧 `from_markdown` 对称——标题走 `--title`,内容文件里别再带 H1 行);连续双 H1 或剥后为空会报错;要让正文以 `#` 行开头须用 `--content` 直传(不做任何剥离)
|
|
126
129
|
|
|
127
130
|
## Test Infrastructure
|
|
128
131
|
|
|
129
132
|
- **Fixtures** (`conftest.py`): `temp_kb` (temp KB path), `cli` (ZKCLI instance), `cli_fast` (ZKCLI with mocked embeddings), `generator` (NoteGenerator), `mock_embedding_backend`
|
|
130
133
|
- **Test utils** (`tests/utils/`): `temp_kb.py`, `jfox_cli.py` (CLI wrapper), `note_generator.py`
|
|
131
|
-
- **全局配置隔离**: conftest 设 `ZK_CONFIG_PATH`(配合既有 `ZK_KB_ROOT`)指向临时目录,pytest 及其拉起的 CLI 子进程不读写真实 `~/.zk_config.json`(#469,`global_config.py` 的 `DEFAULT_CONFIG_PATH` 支持该 env 覆盖);`JFOX_SYNTHESIS_DB` 同样无条件指临时路径,防 DedupStore 单例写真实 `~/.zettelkasten/synthesis_log.db`(#483)
|
|
134
|
+
- **全局配置隔离**: conftest 设 `ZK_CONFIG_PATH`(配合既有 `ZK_KB_ROOT`)指向临时目录,pytest 及其拉起的 CLI 子进程不读写真实 `~/.zk_config.json`(#469,`global_config.py` 的 `DEFAULT_CONFIG_PATH` 支持该 env 覆盖);`JFOX_SYNTHESIS_DB` 同样无条件指临时路径,防 DedupStore 单例写真实 `~/.zettelkasten/synthesis_log.db`(#483);`JFOX_FRAGMENTS_DB`/`JFOX_BACKUP_ROOT`/`JFOX_CLAUDE_PROJECTS_DIR` 同理,防子进程合同测试读写真实 fragments.db、`~/.jfox-backup` 与 `~/.claude/projects`(#531)
|
|
135
|
+
- **测试生成笔记标题须全局唯一**: #483 add 防重闸门会拒绝重复标题,曾致 nightly flaky(#523);`tests/utils/note_generator.py` 已做无放回抽取 + 跨调用标题去重,自写测试生成器同理
|
|
132
136
|
- **Model caching**: Session-level model cache in conftest.py to avoid 30-60s reload per test
|
|
133
137
|
- **Test markers**: `slow`, `performance`, `integration`, `embedding`, `workflow`, `bulk`, `no_embed`(#519:需在无 sentence-transformers 环境执行的降级测试,CI Fast 天然满足)
|
|
138
|
+
- **无 embed 环境测试三坑**(#519 实测):① 测 post-gate 流程(daemon start/restart、ingest、index rebuild 后半段)的单测须 monkeypatch `is_local_embed_available` 为 True,否则无 embed 环境 gate short-circuit、目标流程 0 调用;② mock VectorStore 的单测须设 `mock_vs.last_embed_warning = None`(同 #383 dim-warning 先例),否则残留告警断言失败;③ 用例/类命名避开 "search"/"semantic"/"embedding"/"vector"/"query"/"suggest" 子串——conftest collection 过滤先 nodeid lower() 再子串匹配,命中即整组 deselect(类名也算,`TestSearchModes` 因含 "search" 被整类 slow);pin 零语义场景用 autouse fixture 设 `JFOX_DAEMON_PROCESS=1`(隔离开发机真实 daemon),勿模块级 `os.environ`(collection 阶段写入毒化同进程其他测试文件)
|
|
134
139
|
- **Run single-process** to avoid ChromaDB/model loading conflicts
|
|
135
140
|
- **Test directory reorganization mostly complete**:
|
|
136
141
|
- `tests/unit/` — Pure logic unit tests (25 files)
|
|
@@ -143,7 +148,7 @@ Notes are Markdown files with YAML frontmatter stored under `~/.zettelkasten/<kb
|
|
|
143
148
|
|
|
144
149
|
Four jobs in `.github/workflows/integration-test.yml`:
|
|
145
150
|
|
|
146
|
-
- **Fast** (PR/push): `not embedding and not slow`, Python 3.11, Ubuntu + Windows
|
|
151
|
+
- **Fast** (PR/push): `not embedding and not slow`, Python 3.11, Ubuntu + Windows;另跑 pi-plugin node 测试(setup-node 22,#462)
|
|
147
152
|
- **Core** (main branch): Core workflow tests with real embeddings, Python 3.10 + 3.12
|
|
148
153
|
- **Full** (manual): All tests, all OS, all Python versions
|
|
149
154
|
- **Coverage** (after fast): Runs coverage on fast tests, uploads HTML/XML artifacts
|
|
@@ -184,9 +189,10 @@ JFox ships as a Claude Code plugin. Two-tier structure:
|
|
|
184
189
|
- `packages/cc-plugin/.claude-plugin/plugin.json` — plugin source metadata
|
|
185
190
|
- `packages/cc-plugin/skills/` — 9 skills: `search`, `ingest`, `manage`, `organize`, `promote`, `session-summary`, `session-to-permanent`, `using-jfox`, `bookshelf`
|
|
186
191
|
|
|
187
|
-
**Plugin versioning**: bump version in **three** places together — `packages/cc-plugin/.claude-plugin/plugin.json` (`version`) and both version fields in `.claude-plugin/marketplace.json` (`metadata.version` + `plugins[0].version`). 漏改任一处都会导致 marketplace 与 plugin 版本不一致。Current: 0.7.
|
|
192
|
+
**Plugin versioning**: bump version in **three** places together — `packages/cc-plugin/.claude-plugin/plugin.json` (`version`) and both version fields in `.claude-plugin/marketplace.json` (`metadata.version` + `plugins[0].version`). 漏改任一处都会导致 marketplace 与 plugin 版本不一致。Current: 0.7.6.
|
|
188
193
|
**Skill rename history**: `kb` → `manage` (v0.2.0) — "manage" is the canonical KB lifecycle + CRUD skill.
|
|
189
194
|
**Non-Claude-Code platforms**: `skills-recommend/`(`pi/` + `kimi-cli/`)是 pi / Kimi CLI 适配版 SKILL.md 集(如 `pi/jfox-moc`,#419)——CLI 语义或命令面变更时须与 cc-plugin skills 同步更新。
|
|
195
|
+
**pi prompt 采集扩展**(#462):`packages/pi-plugin/extensions/jfox-prompt-capture.ts`(TypeScript 单文件、零 npm 依赖、node ≥ 22.6 直跑)监听 pi input 事件→合成 CC 兼容事件→原子写 spool 再尽力 POST daemon `/api/prompt`,与 cc-plugin hook 同链路、复用 `jfox prompts drain` 兜底;`user_prompts.source` 由 `prompts/service.py` 透传顶层 source(pi → `pi-coding-agent`,CC 默认 `claude-code`);本地测试 `node --experimental-strip-types packages/pi-plugin/test/run-tests.ts`
|
|
190
196
|
**Skill 多副本同步**: skill 文案/行为改动须同步所有镜像副本——`packages/cc-plugin/skills/`、`packages/kimi-plugin/skills/`、`skills-recommend/kimi-cli/`、`skills-recommend/pi/`,只改一处会各端行为分叉(#440 踩过同步模式)
|
|
191
197
|
|
|
192
198
|
## Branch Rules
|
|
@@ -204,3 +210,4 @@ JFox ships as a Claude Code plugin. Two-tier structure:
|
|
|
204
210
|
- `HybridSearchEngine` 构造时仅对自取的 BM25 单例做一次 stale 检查并 reload(磁盘被其他进程写过则刷新快照);显式传入的 `bm25_index` 实例归调用方所有、不隐式 reload——长驻进程须自行周期重建引擎或调 `check_stale_and_reload`(#391)
|
|
205
211
|
- `jfox index verify` 以 frontmatter 真实 `id` 对账向量库,文件名格式无关——legacy `14位时间戳-6位微秒-slug` 文件名不再误报 orphan;frontmatter 缺 id/解析失败的文件计入 `unreadable_files` 不参与对账,同 id 多文件报 `duplicate_ids`(#407/#408)
|
|
206
212
|
- CPU 默认 embedding 模型已从 `all-MiniLM-L6-v2`(384 维)切到 `BAAI/bge-small-zh-v1.5`(512 维,#442):旧 KB 向量库维度不匹配时 search/add 显式告警不静默失败(`vector_store.last_dimension_warning`),按提示 `jfox index rebuild` 重建该 KB;CI 模型缓存 key 也随模型名(#453)
|
|
213
|
+
- 语义组件缺失降级(#519):无本地 sentence-transformers 且无 daemon 时,写路径降级继续——`save_note`/`update_note` typed catch `EmbedDependencyMissingError`(文件+BM25 照写、跳过向量索引),`update_note` 改走 `add_or_update_note` 守卫原语(服务不可用不删既有行),`index rebuild` 降级 BM25-only 不重置向量库,add/edit JSON 出 `semantic_index_warning`;读路径显式拒绝——search/query/suggest-links 的 semantic/hybrid 模式 exit 1 + 安装提示;`jfox status` JSON 含 `embedding` 探测节(local_package/daemon_running/service_available)
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Issue #548:相邻空反引号对吞 wiki link 修复 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:** 把 `_strip_wiki_link_exclusions` 的三次顺序 `re.sub` 改为单次遍历合并正则,修复「反引号包 HTML 注释」塌缩出相邻空反引号对、吞掉后续 wiki link 的 bug(issue #548)。
|
|
6
|
+
|
|
7
|
+
**Architecture:** 纯函数内部实现替换(签名不变),模块级预编译 `_EXCLUSION_RE`,alternation 顺序 fenced > HTML 注释 > inline code 即优先级。三个调用方(`resolve_wiki_links` / `find_notes_referencing_title` / `note.py` 链接提取)自动受益,无需改动。spec 见 `docs/superpowers/specs/2026-09-24-adjacent-backticks-swallow-wiki-links-design.md`。
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Python 3.10+,`re`(标准库),pytest。
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Work from: `/home/elling/git-repo/github/jfox/.pi/worktrees/issue-548-adjacent-backticks-swallow-wiki-links`(所有路径以它为根;禁止碰主 checkout 的 main)
|
|
14
|
+
- 注释用中文;commit message 用英文 Conventional Commits(`fix:`/`test:`/`docs:`)
|
|
15
|
+
- 验收矩阵(spec):A1/A2=unit,A3=integration,U1=用户实测(post-merge)
|
|
16
|
+
- 测试命名避开子串 `search`/`semantic`/`embedding`/`vector`/`query`/`suggest`(conftest collection 过滤会整组 deselect)
|
|
17
|
+
- 测试生成笔记标题须全局唯一(#483 防重闸门):本 plan 所有标题带 `548` 前缀
|
|
18
|
+
- 范围纪律:不碰 #458(`_normalize_wiki_link_title`)、#470(edit 去重)、`redirect.py`、`graph.py`
|
|
19
|
+
- 改完跑 `uv run ruff check jfox/note_index.py tests/` 与 `uv run black --check jfox/note_index.py tests/unit/test_wiki_link_resolution.py tests/integration/test_backlinks.py`
|
|
20
|
+
- `git add` 按文件 stage,禁止 `git add -A`
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### Task 1: 合并正则修复 + unit 回归用例①–⑥(A1/A2)
|
|
25
|
+
|
|
26
|
+
**Files:**
|
|
27
|
+
|
|
28
|
+
- Modify: `jfox/note_index.py`(`_WIKI_LINK_RE` 定义之后加 `_EXCLUSION_RE`;替换 `_strip_wiki_link_exclusions` 函数体,约 42–53 行)
|
|
29
|
+
- Test: `tests/unit/test_wiki_link_resolution.py`(`TestStripWikiLinkExclusions` 类追加 6 个用例)
|
|
30
|
+
|
|
31
|
+
**Interfaces:**
|
|
32
|
+
|
|
33
|
+
- Consumes: 无(首任务)
|
|
34
|
+
- Produces: `_strip_wiki_link_exclusions(text: str) -> str`(签名不变,行为修复);模块级 `_EXCLUSION_RE`。Task 2 的集成测试经 CLI 间接消费此行为。
|
|
35
|
+
|
|
36
|
+
- [ ] **Step 1: 写失败测试(用例①–⑥)**
|
|
37
|
+
|
|
38
|
+
在 `tests/unit/test_wiki_link_resolution.py` 的 `TestStripWikiLinkExclusions` 类内、`test_plain_text_untouched` 之后追加:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
# ---- #548 回归:反引号包 HTML 注释塌缩成相邻空反引号对 ----
|
|
42
|
+
|
|
43
|
+
def test_backtick_wrapped_html_comment_keeps_following_wiki_link(self):
|
|
44
|
+
"""①/A1:反引号包注释删除后空反引号对不吞后续 wiki link"""
|
|
45
|
+
text = "页首标记 `<!-- print p.X -->` 说明\n\n见 [[笔记A]] 和 `code`"
|
|
46
|
+
out = _strip_wiki_link_exclusions(text)
|
|
47
|
+
assert "[[笔记A]]" in out
|
|
48
|
+
|
|
49
|
+
def test_double_backtick_comment_pair_bracketing_wiki_link(self):
|
|
50
|
+
"""③/A1:两个「反引号包注释」夹住的链接存活(双塌缩形态)"""
|
|
51
|
+
text = "`<!-- a -->` [[笔记A]] `<!-- b -->`"
|
|
52
|
+
out = _strip_wiki_link_exclusions(text)
|
|
53
|
+
assert "[[笔记A]]" in out
|
|
54
|
+
|
|
55
|
+
def test_backtick_comment_without_trailing_backtick(self):
|
|
56
|
+
"""②/A2 对照:触发形态但后文无更多反引号(修复前后均正确,防过修)"""
|
|
57
|
+
text = "页首标记 `<!-- print p.X -->` 见 [[笔记A]]"
|
|
58
|
+
out = _strip_wiki_link_exclusions(text)
|
|
59
|
+
assert "[[笔记A]]" in out
|
|
60
|
+
|
|
61
|
+
def test_fenced_block_with_comment_inside_priority_unchanged(self):
|
|
62
|
+
"""④/A2 对照:fenced 优先级不变——块内链接不提取、块外存活"""
|
|
63
|
+
text = "```\n<!-- c --> [[不应解析]]\n```\n\n见 [[笔记A]]"
|
|
64
|
+
out = _strip_wiki_link_exclusions(text)
|
|
65
|
+
assert "[[不应解析]]" not in out
|
|
66
|
+
assert "[[笔记A]]" in out
|
|
67
|
+
|
|
68
|
+
def test_inline_code_link_still_not_extracted(self):
|
|
69
|
+
"""⑤/A2 对照:inline code 内的链接仍不提取"""
|
|
70
|
+
text = "见 `[[不应解析]]` 和 [[笔记A]]"
|
|
71
|
+
out = _strip_wiki_link_exclusions(text)
|
|
72
|
+
assert "[[不应解析]]" not in out
|
|
73
|
+
assert "[[笔记A]]" in out
|
|
74
|
+
|
|
75
|
+
def test_html_comment_containing_backticks_removed_whole(self):
|
|
76
|
+
"""⑥/A2 对照:注释内含反引号——注释整体剔除、注释外链接存活"""
|
|
77
|
+
text = "<!-- `code` --> 见 [[笔记A]]"
|
|
78
|
+
out = _strip_wiki_link_exclusions(text)
|
|
79
|
+
assert "`code`" not in out
|
|
80
|
+
assert "[[笔记A]]" in out
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- [ ] **Step 2: 跑测试确认按预期失败**
|
|
84
|
+
|
|
85
|
+
Run: `uv run pytest tests/unit/test_wiki_link_resolution.py -k "backtick or fenced_block_with_comment or inline_code_link or html_comment_containing" -v`
|
|
86
|
+
Expected: **仅 ① `test_backtick_wrapped_html_comment_keeps_following_wiki_link` 与 ③ `test_double_backtick_comment_pair_bracketing_wiki_link` FAIL**(断言 `[[笔记A]]` 不在输出),②④⑤⑥ PASS。若失败面大于此,先停下核对环境。
|
|
87
|
+
|
|
88
|
+
- [ ] **Step 3: 实现——合并正则**
|
|
89
|
+
|
|
90
|
+
3a. 在 `jfox/note_index.py` 模块级 `_WIKI_LINK_RE = re.compile(r"\[\[(.*?)\]\]")` 之后空一行插入:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# 单次遍历剔除:alternation 顺序即优先级(fenced > HTML 注释 > inline code),
|
|
94
|
+
# 保证 `<!-- -->` 这类「反引号包注释」在首个反引号处被 inline 分支原子吃掉,
|
|
95
|
+
# 不产生相邻空反引号对。禁止拆回多次顺序 re.sub——顺序剔除会让已删除区域
|
|
96
|
+
# 造出新结构(#548:注释删除→空反引号对→inline 跨界吞链接)。
|
|
97
|
+
_EXCLUSION_RE = re.compile(
|
|
98
|
+
r"```[\s\S]*?```" # fenced code block
|
|
99
|
+
r"|<!--[\s\S]*?-->" # HTML 注释
|
|
100
|
+
r"|`[^`]+`", # inline code(反引号 span)
|
|
101
|
+
)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
3b. 把 `_strip_wiki_link_exclusions` 整个函数(含 docstring 与三行 `re.sub`)替换为:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
def _strip_wiki_link_exclusions(text: str) -> str:
|
|
108
|
+
"""移除不应参与 wiki-link 匹配的 Markdown 区域(fenced code block、HTML 注释、inline code)。
|
|
109
|
+
|
|
110
|
+
单次遍历(见 _EXCLUSION_RE 注释);轻量级处理,不保证解析所有 Markdown 边界情况。
|
|
111
|
+
"""
|
|
112
|
+
return _EXCLUSION_RE.sub("", text)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- [ ] **Step 4: 跑测试确认全过**
|
|
116
|
+
|
|
117
|
+
Run: `uv run pytest tests/unit/test_wiki_link_resolution.py -v`
|
|
118
|
+
Expected: 全部 PASS(既有 3 个用例 + 新增 6 个)。
|
|
119
|
+
|
|
120
|
+
- [ ] **Step 5: lint**
|
|
121
|
+
|
|
122
|
+
Run: `uv run ruff check jfox/note_index.py tests/unit/test_wiki_link_resolution.py && uv run black --check jfox/note_index.py tests/unit/test_wiki_link_resolution.py`
|
|
123
|
+
Expected: 无告警;black 若报格式,跑 `uv run black jfox/note_index.py tests/unit/test_wiki_link_resolution.py` 后复检。
|
|
124
|
+
|
|
125
|
+
- [ ] **Step 6: Commit**
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git add jfox/note_index.py tests/unit/test_wiki_link_resolution.py
|
|
129
|
+
git commit -m "fix(note_index): merge exclusion regexes into single pass to stop adjacent-backtick link loss (#548)"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Task 2: 集成用例——add 落库后 links/backlink 不丢(A3)
|
|
135
|
+
|
|
136
|
+
**Files:**
|
|
137
|
+
|
|
138
|
+
- Modify: `tests/integration/test_backlinks.py`(文件末尾追加测试类)
|
|
139
|
+
- Test: 即本文件
|
|
140
|
+
|
|
141
|
+
**Interfaces:**
|
|
142
|
+
|
|
143
|
+
- Consumes: Task 1 修复后的 `_strip_wiki_link_exclusions` 行为(经 `jfox add` → `resolve_wiki_links` 间接消费);`ZKCLI.add(content, title=, note_type=)`、`ZKCLI.refs(note_id=)`、`ZKCLI._run("show", <id>)`(JSON 输出)。
|
|
144
|
+
- Produces: 无(叶子任务)。
|
|
145
|
+
|
|
146
|
+
- [ ] **Step 1: 写集成测试**
|
|
147
|
+
|
|
148
|
+
在 `tests/integration/test_backlinks.py` 末尾追加(该文件已有 `pytestmark = [pytest.mark.integration, pytest.mark.slow]` 与 `cli` fixture 用法):
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
class TestWikiLinkExclusionOnAdd:
|
|
152
|
+
"""#548:反引号包 HTML 注释不吞落库链接(add → backlink/links 全链路)"""
|
|
153
|
+
|
|
154
|
+
def test_add_keeps_link_after_backtick_wrapped_html_comment(self, cli):
|
|
155
|
+
"""A3:add 含触发内容的笔记后,目标收到 backlink、源笔记 links 含目标 id"""
|
|
156
|
+
# 1. 创建目标笔记
|
|
157
|
+
target = cli.add("Target content", title="548 Target Note", note_type="permanent")
|
|
158
|
+
assert target.success
|
|
159
|
+
target_id = target.data["note"]["id"]
|
|
160
|
+
|
|
161
|
+
# 2. 创建源笔记:反引号包 HTML 注释 + 紧随的 wiki link + 后文反引码(触发形态)
|
|
162
|
+
content = (
|
|
163
|
+
"页首标记 `<!-- print p.X -->` 说明\n\n"
|
|
164
|
+
"见 [[548 Target Note]] 和 `code`"
|
|
165
|
+
)
|
|
166
|
+
source = cli.add(content, title="548 Source Note", note_type="permanent")
|
|
167
|
+
assert source.success
|
|
168
|
+
source_id = source.data["note"]["id"]
|
|
169
|
+
|
|
170
|
+
# 3. 目标笔记必须收到反向链接(issue 症状:backlinks 缺失)
|
|
171
|
+
refs_result = cli.refs(note_id=target_id)
|
|
172
|
+
assert refs_result.success
|
|
173
|
+
backlink_ids = [link["id"] for link in refs_result.data.get("backward_links", [])]
|
|
174
|
+
assert source_id in backlink_ids, f"backlink 缺失:{backlink_ids}"
|
|
175
|
+
|
|
176
|
+
# 4. 源笔记存储的 links 含目标 id(issue 复现口径:show --json 的 links)
|
|
177
|
+
show_result = cli._run("show", source_id)
|
|
178
|
+
assert show_result.success
|
|
179
|
+
assert target_id in (show_result.json or {}).get("links", [])
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
- [ ] **Step 2: 跑集成测试确认通过**
|
|
183
|
+
|
|
184
|
+
Run: `uv run pytest tests/integration/test_backlinks.py::TestWikiLinkExclusionOnAdd -v`
|
|
185
|
+
Expected: PASS。(若在 Task 1 之前先跑本步骤应 FAIL——实现顺序上 Task 1 已合入本 worktree 分支,故直接 PASS;如需复核 bug 形态,可 `git stash` Task 1 的 note_index.py 改动后重跑,应 FAIL。)
|
|
186
|
+
|
|
187
|
+
- [ ] **Step 3: 全量回归本 issue 触及的测试面**
|
|
188
|
+
|
|
189
|
+
Run: `uv run pytest tests/unit/test_wiki_link_resolution.py tests/integration/test_backlinks.py -v`
|
|
190
|
+
Expected: 全部 PASS。
|
|
191
|
+
|
|
192
|
+
- [ ] **Step 4: lint**
|
|
193
|
+
|
|
194
|
+
Run: `uv run ruff check tests/integration/test_backlinks.py && uv run black --check tests/integration/test_backlinks.py`
|
|
195
|
+
Expected: 无告警。
|
|
196
|
+
|
|
197
|
+
- [ ] **Step 5: Commit**
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
git add tests/integration/test_backlinks.py
|
|
201
|
+
git commit -m "test(backlinks): add #548 regression — link survives backtick-wrapped HTML comment"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Post-merge:U1 手动验证(不在本 plan 的代码任务内)
|
|
207
|
+
|
|
208
|
+
修复合入 main 后,由用户对 issue 中命中的那条笔记执行(spec U1):
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
jfox edit <受影响笔记id> --content-file <该笔记原文件> # 重存触发 links 重算
|
|
212
|
+
jfox show <受影响笔记id> --json | jq '.links | length' # 应恢复为 3
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
通过标准:links 条数恢复、缺失的那条 backlink 重新出现。完成后在 issue #548 评论核对结果并关闭 issue。
|
|
216
|
+
|
|
217
|
+
## 验收对账表
|
|
218
|
+
|
|
219
|
+
| 验收 ID | 承载 | 验证命令 |
|
|
220
|
+
|---------|------|----------|
|
|
221
|
+
| A1 | Task 1 用例①③ + 实现 | `uv run pytest tests/unit/test_wiki_link_resolution.py -k backtick` |
|
|
222
|
+
| A2 | Task 1 用例②④⑤⑥ + 既有用例 | `uv run pytest tests/unit/test_wiki_link_resolution.py` |
|
|
223
|
+
| A3 | Task 2 集成用例 | `uv run pytest tests/integration/test_backlinks.py::TestWikiLinkExclusionOnAdd` |
|
|
224
|
+
| U1 | Post-merge 手动步骤 | 见上节,用户执行后在 issue 留痕 |
|
jfox_cli-1.16.1/docs/superpowers/specs/2026-09-24-adjacent-backticks-swallow-wiki-links-design.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Issue #548 Spec:修复 `_strip_wiki_link_exclusions` 吞掉后续 wiki link
|
|
2
|
+
|
|
3
|
+
> 日期:2026-09-24 · 类型:bug · issue:#548 · 调研存档:`~/.claude/github-issue-driven/zhuxixi/jfox/issue-548/research/`
|
|
4
|
+
> 修订:2026-09-24 v2 —— 按 spec review 发现 R1–R6 修订(见文末修订记录)
|
|
5
|
+
|
|
6
|
+
## 一句话设计
|
|
7
|
+
|
|
8
|
+
把 `_strip_wiki_link_exclusions`(`jfox/note_index.py:42`)的**三次顺序 `re.sub`** 改成**单次遍历的合并正则(alternation)**,让三类剔除区域在同一次扫描里原子匹配,已删除区域不再参与后续匹配。
|
|
9
|
+
|
|
10
|
+
## 根因(systematic-debugging Phase 1-3 已完成)
|
|
11
|
+
|
|
12
|
+
现状顺序剔除:
|
|
13
|
+
|
|
14
|
+
1. `re.sub(r"```[\s\S]*?```", "", text)` —— fenced code block
|
|
15
|
+
2. `re.sub(r"<!--[\s\S]*?-->", "", text)` —— HTML 注释
|
|
16
|
+
3. `re.sub(r"`[^`]+`", "", text)` —— inline code
|
|
17
|
+
|
|
18
|
+
第 2 步删掉被反引号包住的 HTML 注释(`` `<!-- -->` ``)后,两个反引号塌缩成**相邻空对** `` `` ``;第 3 步`` `[^`]+` `` 在第一个反引号处匹配失败(下一字符是反引号),转而从**第二个**反引号起匹配,一路吃到文中再下一个反引号,把中间整段(含 wiki link)当行内代码删除。
|
|
19
|
+
|
|
20
|
+
已复现:输入 `页首标记 \`<!-- print p.X -->\` 说明\n\n见 [[笔记A]] 和 \`code\``,当前提取链接`[]`,修法提取`['笔记A']`。
|
|
21
|
+
|
|
22
|
+
## 设计
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
# note_index.py 模块级
|
|
26
|
+
|
|
27
|
+
# 单次遍历剔除:alternation 顺序即优先级(fenced > HTML 注释 > inline code),
|
|
28
|
+
# 保证 `` `<!-- -->` `` 这类「反引号包注释」在首个反引号处被 inline 分支原子吃掉,
|
|
29
|
+
# 不产生相邻空反引号对。禁止拆回多次顺序 re.sub——顺序剔除会让已删除区域
|
|
30
|
+
# 造出新结构(#548:注释删除→空反引号对→inline 跨界吞链接)。
|
|
31
|
+
_EXCLUSION_RE = re.compile(
|
|
32
|
+
r"```[\s\S]*?```" # fenced code block
|
|
33
|
+
r"|<!--[\s\S]*?-->" # HTML 注释
|
|
34
|
+
r"|`[^`]+`", # inline code(反引号 span)
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def _strip_wiki_link_exclusions(text: str) -> str:
|
|
38
|
+
"""移除不应参与 wiki-link 匹配的 Markdown 区域(fenced code block、HTML 注释、inline code)。
|
|
39
|
+
|
|
40
|
+
单次遍历(见 _EXCLUSION_RE 注释);轻量级处理,不保证解析所有 Markdown 边界情况。
|
|
41
|
+
"""
|
|
42
|
+
return _EXCLUSION_RE.sub("", text)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**为什么有效**:单次遍历在每个位置按 alternation 顺序(fenced → HTML → inline)尝试。在 `` `<!-- -->` `` 的第一个反引号处,fenced 与 HTML 分支都因当前字符是反引号而失败,inline 分支把整段当行内代码**原子吃掉**——根本不产生空反引号对,后续文字不受影响。alternation 顺序同时保留了原代码「fenced 先于 inline」的意图(原注释「须最后处理,避免吃掉 fenced 边界」)。
|
|
46
|
+
|
|
47
|
+
**为什么不选备选方案**(issue 里也提了):保留顺序剔除、第 2 步后折叠相邻空反引号对(`re.sub(r"``+", "", text)`)。它只堵住这一种塌缩形态,后续新增剔除规则时同类交接问题会复发;合并正则更彻底,且行为与现状在所有非 bug 用例上一致(已用对照用例验证,见「回归用例清单」)。
|
|
48
|
+
|
|
49
|
+
**注释是交付物的一部分(review R4)**:`_EXCLUSION_RE` 上方的注释解释了 alternation 顺序即优先级、以及为什么禁止拆回顺序剔除。没有这段注释,后续维护者很可能按直觉「简化」回多次 `re.sub`,复发同类 bug。
|
|
50
|
+
|
|
51
|
+
## 影响面(review R3 修订:准确版)
|
|
52
|
+
|
|
53
|
+
**fenced+HTML+inline 三合一剔除的实现只有 `note_index.py:42` 一处**,三个调用方都 import 它:
|
|
54
|
+
|
|
55
|
+
| 调用方 | 用途 |
|
|
56
|
+
|--------|------|
|
|
57
|
+
| `cli.py:373` | `resolve_wiki_links`(#511/#530 收敛的 add/edit/rebuild 三路径,含 frontmatter links 写入) |
|
|
58
|
+
| `note_index.py:262` | `find_notes_referencing_title`(backlinks 反查) |
|
|
59
|
+
| `note.py:507` | 笔记链接提取 |
|
|
60
|
+
|
|
61
|
+
**两处相邻实现,不受本 bug 影响、也不在本次改动范围**(review 时 grep 发现,修正调研阶段「全仓唯一实现」的过强表述——那只对函数成立,不对剔除逻辑成立):
|
|
62
|
+
|
|
63
|
+
- `redirect.py:33-34,125-126`:自己的 `_FENCED_CODE_RE`/`_HTML_COMMENT_RE`,顺序 **blank(占位替换,非删除)**,且无 inline-code 步骤——不产生相邻塌缩,不受 #548 影响,无需改动。其注释「与 note_index 扫描口径保持一致」本就不完全成立(redirect 不剔 inline code),改完 note_index 后该口径差依旧存在,属独立话题。
|
|
64
|
+
- `graph.py:97`:第三 pass 对 **raw content** 提取链接、完全不剥离——口径与 note_index 相反,code fence 里的链接在图谱中会计成边。#548 触发的笔记在 graph 里其实**有**边,issue 里「图谱少边」的说法只对 backlinks/stored links 成立。
|
|
65
|
+
|
|
66
|
+
## 非目标
|
|
67
|
+
|
|
68
|
+
- **不捎带 #458**(含 `#` 标题被 `_normalize_wiki_link_title` 截断)、**#470**(edit 去重 + 同名歧义)——不同函数的独立 bug。
|
|
69
|
+
- **不处理 redirect.py / graph.py 的口径分歧**(见影响面;如需统一扫描口径,另开 issue)。
|
|
70
|
+
- **不引入完整 Markdown 解析器**——函数 docstring 声明的轻量口径不变,合并正则仍在该哲学内。
|
|
71
|
+
- **不做批量存量重存工具**——存量补救走 U1 的人工重存路径(见验收矩阵),不为此加 CLI 命令。
|
|
72
|
+
|
|
73
|
+
## 可测性拆分设计
|
|
74
|
+
|
|
75
|
+
`_strip_wiki_link_exclusions` 本来就是**纯函数**(`text -> str`,无副作用、无外部依赖),无需拆分。测试边界:
|
|
76
|
+
|
|
77
|
+
- **unit(A1/A2,主证明)**:直接对纯函数断言输出,无 mock、无 fixture,秒级。
|
|
78
|
+
- **integration(A3,症状层)**:经 `ZKCLI` 走 `add` 落库 → `show --json` 读 `links`,证明用户可观察症状(落库后 links 缺失、且不进 Unresolved 警告)消失。接线本身(#511)已有测试,此处只钉症状。
|
|
79
|
+
- **用户实测(U1,存量补救)**:`edit` 仅在 `content is not None` 时重算 links(`cli.py:1997-1999`),已污染的 frontmatter links **不会自愈**,需对受影响笔记重存一次。
|
|
80
|
+
|
|
81
|
+
## 验收矩阵
|
|
82
|
+
|
|
83
|
+
| ID | 功能点 | 验收方式 | 具体验证 | 通过标准 |
|
|
84
|
+
|----|--------|----------|----------|----------|
|
|
85
|
+
| A1 | 反引号包 HTML 注释后,紧随的 wiki link 被保留 | 自动化验证(unit) | `uv run pytest tests/unit/test_wiki_link_resolution.py -k strip` | 「回归用例清单」① 触发用例通过 |
|
|
86
|
+
| A2 | 既有剥离行为不回归 | 自动化验证(unit) | `uv run pytest tests/unit/test_wiki_link_resolution.py` | 该文件既有用例 + 清单②–⑥对照用例全部通过 |
|
|
87
|
+
| A3 | 端到端:`add` 含触发内容的笔记后,`show --json` 的 `links` 含目标 | 自动化验证(integration) | 新增集成测试(ZKCLI add → show,复用既有 fixtures) | `links` 包含目标笔记 id;触发内容里的链接不静默丢失 |
|
|
88
|
+
| U1 | 存量受污染笔记的 links 恢复 | 用户实测 | 修复合入后,对 issue 中命中的那条笔记执行 `jfox edit <id> --content-file <原文件>`(或 `--content` 原文重存),再 `jfox show <id> --json` 核对 | `links` 条数恢复(该笔记应为 3),缺失的那条 backlink 重新出现 |
|
|
89
|
+
|
|
90
|
+
A3 为必做(review R1:验收矩阵与改动清单不允许「可选」矛盾)。U1 是操作项:修复本身无法自动定位哪条笔记被污染(依赖 issue 记录),故归用户实测。
|
|
91
|
+
|
|
92
|
+
## 回归用例清单(A1/A2 落到 `TestStripWikiLinkExclusions`)
|
|
93
|
+
|
|
94
|
+
| # | 用例 | 期望(修复后) | 防什么 |
|
|
95
|
+
|---|------|----------------|--------|
|
|
96
|
+
| ① | 触发用例:`页首标记 \`<!-- p -->\` 说明\n\n见 [[笔记A]] 和 \`code\`` | `[[笔记A]]` 存活 | #548 本体(A1) |
|
|
97
|
+
| ② | 触发变体·后文无更多反引号 | `[[笔记A]]` 存活(修复前也存活) | 防过修/行为漂移 |
|
|
98
|
+
| ③ | 两个「反引号包注释」夹住一个链接 | 链接存活 | 双塌缩形态(顺序版此形态也丢链) |
|
|
99
|
+
| ④ | fenced block 内含 HTML 注释与链接 | 块内链接不提取,块外链接提取 | fenced 优先级不变 |
|
|
100
|
+
| ⑤ | inline code 内的 `[[...]]` | 不提取 | inline 剥离不变 |
|
|
101
|
+
| ⑥ | HTML 注释内含反引号 | 注释整体剔除、注释外链接存活 | 分支优先级不变 |
|
|
102
|
+
|
|
103
|
+
复现脚本已验证 ①–⑥ 在修复版下全部正确、在现状版下仅 ①③ 有差异(即仅 bug 形态被修)。
|
|
104
|
+
|
|
105
|
+
## 改动文件
|
|
106
|
+
|
|
107
|
+
- `jfox/note_index.py`:`_strip_wiki_link_exclusions` 改为合并正则;新增模块级 `_EXCLUSION_RE`(含解释性注释,见设计节)。
|
|
108
|
+
- `tests/unit/test_wiki_link_resolution.py`:`TestStripWikiLinkExclusions` 增用例①–⑥(A1/A2)。
|
|
109
|
+
- `tests/integration/`(A3 必做):新增或扩展一个 add→show 集成用例。
|
|
110
|
+
|
|
111
|
+
## 修订记录
|
|
112
|
+
|
|
113
|
+
- v2(2026-09-24,spec review 后):
|
|
114
|
+
- R1:A3 从「(可选)」改为必做,矩阵与改动清单一致。
|
|
115
|
+
- R2:新增 U1 存量补救(`edit` 重存触发 links 重算)。
|
|
116
|
+
- R3:影响面改写——「唯一实现」收窄为「三合一剔除唯一实现」,补 redirect.py(顺序 blank,不受影响)与 graph.py(不剥离,口径相反)两处事实。
|
|
117
|
+
- R4:设计节明确注释为交付物,给出注释内容。
|
|
118
|
+
- R5:钉死回归用例清单①–⑥。
|
|
119
|
+
- R6:非目标补三条(redirect/graph 口径分歧、不引 Markdown 解析器、不做批量重存工具)。
|
|
@@ -18,6 +18,18 @@ logger = logging.getLogger(__name__)
|
|
|
18
18
|
# 维基链接正则:匹配 [[标题]] 语法(非贪婪,不支持跨行)
|
|
19
19
|
_WIKI_LINK_RE = re.compile(r"\[\[(.*?)\]\]")
|
|
20
20
|
|
|
21
|
+
# 单次遍历剔除:alternation 顺序即优先级(fenced > HTML 注释 > inline code),
|
|
22
|
+
# 保证 `<!-- -->` 这类「反引号包注释」在首个反引号处被 inline 分支原子吃掉,
|
|
23
|
+
# 不产生相邻空反引号对。禁止拆回多次顺序 re.sub——顺序剔除会让已删除区域
|
|
24
|
+
# 造出新结构(#548:注释删除→空反引号对→inline 跨界吞链接)。
|
|
25
|
+
# 注意:当前三分支在同一扫描位置互斥(fenced 的 ``` 处 inline 必不匹配、HTML 以 `<` 起始),
|
|
26
|
+
# 故今日顺序不改变输出;声明的顺序是防御性文档,约束未来可能在同一位置竞争的分支(如四反引号 fence 变体)。
|
|
27
|
+
_EXCLUSION_RE = re.compile(
|
|
28
|
+
r"```[\s\S]*?```" # fenced code block
|
|
29
|
+
r"|<!--[\s\S]*?-->" # HTML 注释
|
|
30
|
+
r"|`[^`]+`", # inline code(反引号 span)
|
|
31
|
+
)
|
|
32
|
+
|
|
21
33
|
|
|
22
34
|
def extract_wiki_links_from_text(text: str) -> List[str]:
|
|
23
35
|
"""从文本中提取 [[...]] 格式的维基链接。
|
|
@@ -42,15 +54,9 @@ def _normalize_wiki_link_title(link_text: str) -> str:
|
|
|
42
54
|
def _strip_wiki_link_exclusions(text: str) -> str:
|
|
43
55
|
"""移除不应参与 wiki-link 匹配的 Markdown 区域(fenced code block、HTML 注释、inline code)。
|
|
44
56
|
|
|
45
|
-
|
|
57
|
+
单次遍历(见 _EXCLUSION_RE 注释);轻量级处理,不保证解析所有 Markdown 边界情况。
|
|
46
58
|
"""
|
|
47
|
-
|
|
48
|
-
text = re.sub(r"```[\s\S]*?```", "", text)
|
|
49
|
-
# HTML 注释
|
|
50
|
-
text = re.sub(r"<!--[\s\S]*?-->", "", text)
|
|
51
|
-
# inline code(反引号 span;须最后处理,避免吃掉 fenced 边界)
|
|
52
|
-
text = re.sub(r"`[^`]+`", "", text)
|
|
53
|
-
return text
|
|
59
|
+
return _EXCLUSION_RE.sub("", text)
|
|
54
60
|
|
|
55
61
|
|
|
56
62
|
@dataclass
|
|
@@ -136,3 +136,31 @@ class TestBacklinksAutoMaintenance:
|
|
|
136
136
|
|
|
137
137
|
# 验证 A 没有来自 C 的直接反向链接(只有间接通过 B)
|
|
138
138
|
assert id_c not in backlink_ids_a
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class TestWikiLinkExclusionOnAdd:
|
|
142
|
+
"""#548:反引号包 HTML 注释不吞落库链接(add → backlink/links 全链路)"""
|
|
143
|
+
|
|
144
|
+
def test_add_keeps_link_after_backtick_wrapped_html_comment(self, cli):
|
|
145
|
+
"""A3:add 含触发内容的笔记后,目标收到 backlink、源笔记 links 含目标 id"""
|
|
146
|
+
# 1. 创建目标笔记
|
|
147
|
+
target = cli.add("Target content", title="548 Target Note", note_type="permanent")
|
|
148
|
+
assert target.success
|
|
149
|
+
target_id = target.data["note"]["id"]
|
|
150
|
+
|
|
151
|
+
# 2. 创建源笔记:反引号包 HTML 注释 + 紧随的 wiki link + 后文反引码(触发形态)
|
|
152
|
+
content = "页首标记 `<!-- print p.X -->` 说明\n\n" "见 [[548 Target Note]] 和 `code`"
|
|
153
|
+
source = cli.add(content, title="548 Source Note", note_type="permanent")
|
|
154
|
+
assert source.success
|
|
155
|
+
source_id = source.data["note"]["id"]
|
|
156
|
+
|
|
157
|
+
# 3. 目标笔记必须收到反向链接(issue 症状:backlinks 缺失)
|
|
158
|
+
refs_result = cli.refs(note_id=target_id)
|
|
159
|
+
assert refs_result.success
|
|
160
|
+
backlink_ids = [link["id"] for link in refs_result.data.get("backward_links", [])]
|
|
161
|
+
assert source_id in backlink_ids, f"backlink 缺失:{backlink_ids}"
|
|
162
|
+
|
|
163
|
+
# 4. 源笔记存储的 links 含目标 id(issue 复现口径:show --json 的 links)
|
|
164
|
+
show_result = cli._run("show", source_id)
|
|
165
|
+
assert show_result.success
|
|
166
|
+
assert target_id in (show_result.json() or {}).get("links", [])
|
|
@@ -62,6 +62,56 @@ class TestStripWikiLinkExclusions:
|
|
|
62
62
|
out = _strip_wiki_link_exclusions("普通 [[链接]] 内容")
|
|
63
63
|
assert "[[链接]]" in out
|
|
64
64
|
|
|
65
|
+
# ---- #548 回归:反引号包 HTML 注释塌缩成相邻空反引号对 ----
|
|
66
|
+
|
|
67
|
+
def test_backtick_wrapped_html_comment_keeps_following_wiki_link(self):
|
|
68
|
+
"""①/A1:反引号包注释删除后空反引号对不吞后续 wiki link"""
|
|
69
|
+
text = "页首标记 `<!-- print p.X -->` 说明\n\n见 [[笔记A]] 和 `code`"
|
|
70
|
+
out = _strip_wiki_link_exclusions(text)
|
|
71
|
+
assert "[[笔记A]]" in out
|
|
72
|
+
|
|
73
|
+
def test_double_backtick_comment_pair_bracketing_wiki_link(self):
|
|
74
|
+
"""③/A1:两个「反引号包注释」夹住的链接存活(双塌缩形态)"""
|
|
75
|
+
text = "`<!-- a -->` [[笔记A]] `<!-- b -->`"
|
|
76
|
+
out = _strip_wiki_link_exclusions(text)
|
|
77
|
+
assert "[[笔记A]]" in out
|
|
78
|
+
|
|
79
|
+
def test_backtick_comment_without_trailing_backtick(self):
|
|
80
|
+
"""②/A2 对照:触发形态但后文无更多反引号(修复前后均正确,防过修)"""
|
|
81
|
+
text = "页首标记 `<!-- print p.X -->` 见 [[笔记A]]"
|
|
82
|
+
out = _strip_wiki_link_exclusions(text)
|
|
83
|
+
assert "[[笔记A]]" in out
|
|
84
|
+
|
|
85
|
+
def test_fenced_block_with_comment_inside_priority_unchanged(self):
|
|
86
|
+
"""④/A2 对照:fenced 内含 HTML 注释与链接——块内不提取、块外存活(顺序由⑦钉住)"""
|
|
87
|
+
text = "```\n<!-- c --> [[不应解析]]\n```\n\n见 [[笔记A]]"
|
|
88
|
+
out = _strip_wiki_link_exclusions(text)
|
|
89
|
+
assert "[[不应解析]]" not in out
|
|
90
|
+
assert "[[笔记A]]" in out
|
|
91
|
+
|
|
92
|
+
def test_inline_code_link_still_not_extracted(self):
|
|
93
|
+
"""⑤/A2 对照:inline code 内的链接仍不提取"""
|
|
94
|
+
text = "见 `[[不应解析]]` 和 [[笔记A]]"
|
|
95
|
+
out = _strip_wiki_link_exclusions(text)
|
|
96
|
+
assert "[[不应解析]]" not in out
|
|
97
|
+
assert "[[笔记A]]" in out
|
|
98
|
+
|
|
99
|
+
def test_html_comment_containing_backticks_removed_whole(self):
|
|
100
|
+
"""⑥/A2 对照:注释内含反引号——注释整体剔除、注释外链接存活"""
|
|
101
|
+
text = "<!-- `code` --> 见 [[笔记A]]"
|
|
102
|
+
out = _strip_wiki_link_exclusions(text)
|
|
103
|
+
assert "`code`" not in out
|
|
104
|
+
assert "[[笔记A]]" in out
|
|
105
|
+
|
|
106
|
+
def test_fenced_block_with_inner_backtick_and_link_pins_ordering(self):
|
|
107
|
+
"""⑦/A2 对照:fence 内含反引号与链接——fenced 分支须原子吃掉整块,
|
|
108
|
+
块内链接不得因 fence 被行内反引号破坏而泄漏;块外链接存活。
|
|
109
|
+
该用例区分 alternation 顺序(inline 先于 fenced 时会失败)。"""
|
|
110
|
+
text = "```\ncode `t` [[不应解析]]\n```\n\n见 [[笔记A]] 和 `d`"
|
|
111
|
+
out = _strip_wiki_link_exclusions(text)
|
|
112
|
+
assert "[[不应解析]]" not in out
|
|
113
|
+
assert "[[笔记A]]" in out
|
|
114
|
+
|
|
65
115
|
|
|
66
116
|
class TestResolveWikiLinks:
|
|
67
117
|
"""resolve_wiki_links 统一解析规则(issue #511)"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jfox_cli-1.16.0 → jfox_cli-1.16.1}/.claude/skills/release-cc-plugin/release_cc_plugin_helper.py
RENAMED
|
File without changes
|
|
File without changes
|