jfox-cli 1.16.0__tar.gz → 1.16.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (522) hide show
  1. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/CHANGELOG.md +28 -0
  2. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/CLAUDE.md +12 -5
  3. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/PKG-INFO +1 -1
  4. jfox_cli-1.16.2/docs/superpowers/plans/2026-09-24-adjacent-backticks-swallow-wiki-links.md +224 -0
  5. jfox_cli-1.16.2/docs/superpowers/plans/2026-09-24-issue-549-twin-files.md +305 -0
  6. jfox_cli-1.16.2/docs/superpowers/specs/2026-09-24-adjacent-backticks-swallow-wiki-links-design.md +119 -0
  7. jfox_cli-1.16.2/docs/superpowers/specs/2026-09-24-issue-549-twin-files-design.md +121 -0
  8. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/__init__.py +1 -1
  9. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/moc/cli.py +3 -3
  10. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/models.py +32 -4
  11. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/note.py +23 -7
  12. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/note_index.py +14 -8
  13. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/redirect.py +3 -2
  14. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/pyproject.toml +1 -1
  15. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_backlinks.py +28 -0
  16. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_moc_member_commands.py +3 -2
  17. jfox_cli-1.16.2/tests/integration/test_stale_name_single_file.py +306 -0
  18. jfox_cli-1.16.2/tests/unit/test_note_path_rules.py +111 -0
  19. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_wiki_link_resolution.py +50 -0
  20. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/uv.lock +1 -1
  21. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/ci/SKILL.md +0 -0
  22. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release/SKILL.md +0 -0
  23. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release/release_helper.py +0 -0
  24. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release-all/SKILL.md +0 -0
  25. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release-all/release_all_helper.py +0 -0
  26. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release-cc-plugin/SKILL.md +0 -0
  27. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release-cc-plugin/release_cc_plugin_helper.py +0 -0
  28. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release-kimi-plugin/SKILL.md +0 -0
  29. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude/skills/release-kimi-plugin/release_kimi_plugin_helper.py +0 -0
  30. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.claude-plugin/marketplace.json +0 -0
  31. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.githooks/pre-push +0 -0
  32. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  33. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  34. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/ISSUE_TEMPLATE/docs_improvement.yml +0 -0
  35. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  36. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  37. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/workflows/integration-test.yml +0 -0
  38. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.github/workflows/publish.yml +0 -0
  39. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.gitignore +0 -0
  40. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.markdownlint-cli2.jsonc +0 -0
  41. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.pi-lens.json +0 -0
  42. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/.python-version +0 -0
  43. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/AGENTS.md +0 -0
  44. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/DEVELOPMENT_PLAN.md +0 -0
  45. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/README.md +0 -0
  46. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/SESSION.md +0 -0
  47. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/SESSION_SUMMARY.md +0 -0
  48. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/claude-code-plugin-guide.md +0 -0
  49. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/cli-descriptions.yaml +0 -0
  50. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/cli-reference.md +0 -0
  51. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/installation.md +0 -0
  52. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/json-schemas.md +0 -0
  53. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/nightly-test.md +0 -0
  54. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/plugin-inventory.md +0 -0
  55. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-11-bulk-import-bm25-fix.md +0 -0
  56. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-11-edit-command.md +0 -0
  57. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-11-unify-format-option.md +0 -0
  58. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-ci-coverage-optimization.md +0 -0
  59. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-edit-content-file.md +0 -0
  60. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-fix-index-rebuild-clear.md +0 -0
  61. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-fix-index-verify-id-mismatch.md +0 -0
  62. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-fix-jfox-health-skill-kb-param.md +0 -0
  63. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-index-kb-param.md +0 -0
  64. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-lazy-import-perf.md +0 -0
  65. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-12-skill-redesign.md +0 -0
  66. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-13-add-content-file.md +0 -0
  67. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-13-bulk-import-vectorstore-init.md +0 -0
  68. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-13-ingest-log-command.md +0 -0
  69. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-13-ingest-skill-sync.md +0 -0
  70. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-13-suppress-third-party-logging.md +0 -0
  71. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-13-sync-skills-with-cli.md +0 -0
  72. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-14-sync-docs-daemon-show.md +0 -0
  73. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-15-gpu-embedding.md +0 -0
  74. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-15-make-daemon-deps-required.md +0 -0
  75. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-15-session-summary-confirmation.md +0 -0
  76. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-16-fix-windows-daemon-console-window.md +0 -0
  77. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-18-daemon-timeout-and-index-rebuild.md +0 -0
  78. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-22-release-skill.md +0 -0
  79. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-26-fix-daemon-deprecation-warnings.md +0 -0
  80. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-27-intranet-model-download.md +0 -0
  81. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-28-tag-filtering.md +0 -0
  82. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-04-29-daemon-stop-fix.md +0 -0
  83. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-03-jfox-check.md +0 -0
  84. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-03-list-notes-skip-summary.md +0 -0
  85. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-03-log-level-fix.md +0 -0
  86. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-04-list-notes-index.md +0 -0
  87. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-06-atomic-write.md +0 -0
  88. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-09-session-note-type.md +0 -0
  89. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-10-jfox-plugin.md +0 -0
  90. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-19-fix-last-used-never.md +0 -0
  91. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-05-20-modelscope-migration.md +0 -0
  92. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-02-todo-note-type.md +0 -0
  93. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-16-kimi-code-auto-summary.md +0 -0
  94. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-17-index-rebuild-backlinks.md +0 -0
  95. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-17-using-jfox-skill.md +0 -0
  96. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-18-self-update-command.md +0 -0
  97. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-21-fragment-capture.md +0 -0
  98. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-21-gem-synthesis.md +0 -0
  99. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-06-25-gem-synth-throttle-ledger.md +0 -0
  100. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-08-auto-summary-schedule-window.md +0 -0
  101. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-08-candidate-promote.md +0 -0
  102. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-12-gem-synth-dedup.md +0 -0
  103. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-12-release-cc-plugin-skill.md +0 -0
  104. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-12-session-summary-streamline.md +0 -0
  105. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-12-show-json.md +0 -0
  106. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-17-fix-candidate-dual-h1.md +0 -0
  107. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-18-dedup-lifecycle-decouple.md +0 -0
  108. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-19-promote-skill-three-modes.md +0 -0
  109. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-25-bookshelf.md +0 -0
  110. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-25-gem-synth-dedup-incremental-merge.md +0 -0
  111. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-26-kb-backup-restore.md +0 -0
  112. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-26-promote-skill-clear-reports-rewrite.md +0 -0
  113. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-27-release-all.md +0 -0
  114. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-28-bookshelf-flat-bundle.md +0 -0
  115. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-07-28-nightly-fulltest.md +0 -0
  116. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-07-session-to-permanent-cc-kimi.md +0 -0
  117. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-11-permanent-note-template.md +0 -0
  118. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-12-noteindex-frontmatter-limit-drop.md +0 -0
  119. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-15-delete-backlinks-cleanup.md +0 -0
  120. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-16-bm25-concurrent-write-race.md +0 -0
  121. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-21-index-verify-legacy-filenames.md +0 -0
  122. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-21-moc-density-diagnose.md +0 -0
  123. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-22-bm25-type-debt-cleanup.md +0 -0
  124. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-22-issue-392-cr-leftovers.md +0 -0
  125. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-22-jfox-moc-skill.md +0 -0
  126. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-22-markdownlint-adoption.md +0 -0
  127. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-22-moc-create-update.md +0 -0
  128. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-25-moc-create-update-json-shorthand.md +0 -0
  129. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-27-issue-436-organize-archive.md +0 -0
  130. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-28-cpu-default-model-bge-small-zh.md +0 -0
  131. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-29-english-readme-baseline.md +0 -0
  132. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-29-issue-383-add-permanent-dedup.md +0 -0
  133. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-29-louvain-moc-clustering.md +0 -0
  134. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-30-gem-synth-prompt-judgment.md +0 -0
  135. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-30-test-config-isolation.md +0 -0
  136. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-08-31-deterministic-cli-reference.md +0 -0
  137. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-01-ci-docs-drift-gate.md +0 -0
  138. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-02-plugin-inventory-enum-checks.md +0 -0
  139. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-03-jfox-moc-batch-quality-chapter.md +0 -0
  140. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-03-moc-member-management.md +0 -0
  141. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-04-chromadb-dim-migration-ndarray.md +0 -0
  142. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-05-moc-diagnose-archived-orphan.md +0 -0
  143. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-07-bm25-fresh-kb-logging.md +0 -0
  144. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-07-pi-prompt-capture.md +0 -0
  145. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-09-from-dict-non-dict-guard.md +0 -0
  146. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-09-nightly-test-failures.md +0 -0
  147. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-10-skill-sync-399-overview-jfox-judge.md +0 -0
  148. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-14-json-schema-unify.md +0 -0
  149. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-14-lightweight-install.md +0 -0
  150. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-14-wiki-link-self-link.md +0 -0
  151. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/plans/2026-09-23-h1-strip-normalization.md +0 -0
  152. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-03-bugfixes-design.md +0 -0
  153. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-12-skill-redesign-design.md +0 -0
  154. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-13-pr-auto-code-review-design.md +0 -0
  155. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-14-show-command-design.md +0 -0
  156. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-15-gpu-embedding-design.md +0 -0
  157. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-15-session-summary-confirmation-design.md +0 -0
  158. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-21-release-skill-design.md +0 -0
  159. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-26-fix-daemon-deprecation-warnings-design.md +0 -0
  160. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-27-intranet-model-download-design.md +0 -0
  161. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-28-tag-filtering-design.md +0 -0
  162. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-29-daemon-stop-fix-design.md +0 -0
  163. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-04-30-jfox-kb-env-var-design.md +0 -0
  164. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-03-jfox-check-design.md +0 -0
  165. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-03-list-notes-skip-summary-design.md +0 -0
  166. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-03-log-level-fix-design.md +0 -0
  167. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-04-list-notes-index-design.md +0 -0
  168. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-06-atomic-write-design.md +0 -0
  169. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-09-jfox-plugin-design.md +0 -0
  170. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-09-session-note-type-design.md +0 -0
  171. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-05-20-modelscope-migration-design.md +0 -0
  172. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-02-todo-note-type-design.md +0 -0
  173. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-16-kimi-code-auto-summary-design.md +0 -0
  174. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-17-index-rebuild-backlinks-design.md +0 -0
  175. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-17-using-jfox-skill-design.md +0 -0
  176. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-18-archive-soft-delete-design.md +0 -0
  177. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-18-self-update-command-design.md +0 -0
  178. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-21-fragment-capture-design.md +0 -0
  179. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-21-gem-synthesis-design.md +0 -0
  180. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-06-25-gem-synth-throttle-ledger-design.md +0 -0
  181. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-08-candidate-promote-design.md +0 -0
  182. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-12-gem-synth-dedup-design.md +0 -0
  183. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-12-release-cc-plugin-skill-design.md +0 -0
  184. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-12-session-summary-streamline-design.md +0 -0
  185. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-12-show-json-design.md +0 -0
  186. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-18-dedup-lifecycle-decouple-design.md +0 -0
  187. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-19-promote-skill-three-modes-design.md +0 -0
  188. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-25-bookshelf-design.md +0 -0
  189. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-25-gem-synth-dedup-incremental-merge-design.md +0 -0
  190. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-26-kb-backup-restore-design.md +0 -0
  191. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-26-promote-skill-clear-reports-rewrite-design.md +0 -0
  192. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-27-release-all-orchestration-design.md +0 -0
  193. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-28-bookshelf-flat-bundle-design.md +0 -0
  194. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-07-28-nightly-fulltest-design.md +0 -0
  195. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-07-session-to-permanent-cc-kimi-design.md +0 -0
  196. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-11-permanent-note-template-design.md +0 -0
  197. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-12-noteindex-frontmatter-limit-drop-design.md +0 -0
  198. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-15-delete-backlinks-cleanup-design.md +0 -0
  199. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-16-bm25-concurrent-write-race-design.md +0 -0
  200. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-20-bm25-clear-orphan-followup-design.md +0 -0
  201. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-21-index-verify-legacy-filenames-design.md +0 -0
  202. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-21-moc-density-diagnose-design.md +0 -0
  203. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-22-bm25-type-debt-cleanup-design.md +0 -0
  204. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-22-issue-392-cr-leftovers-design.md +0 -0
  205. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-22-jfox-moc-skill-design.md +0 -0
  206. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-22-markdownlint-adoption-design.md +0 -0
  207. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-22-moc-create-update-design.md +0 -0
  208. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-25-moc-create-update-json-shorthand-design.md +0 -0
  209. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-27-issue-436-organize-archive-design.md +0 -0
  210. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-27-redirect-and-delete-guard.md +0 -0
  211. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-28-cpu-default-model-bge-small-zh-design.md +0 -0
  212. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-29-english-readme-baseline-design.md +0 -0
  213. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-29-issue-383-add-permanent-dedup-design.md +0 -0
  214. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-29-louvain-moc-clustering-design.md +0 -0
  215. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-30-gem-synth-prompt-judgment-design.md +0 -0
  216. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-30-test-config-isolation-design.md +0 -0
  217. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-08-31-deterministic-cli-reference-design.md +0 -0
  218. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-01-ci-docs-drift-gate-design.md +0 -0
  219. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-02-plugin-inventory-enum-checks-design.md +0 -0
  220. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-03-jfox-moc-batch-quality-chapter-design.md +0 -0
  221. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-03-moc-member-management-design.md +0 -0
  222. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-04-chromadb-dim-migration-ndarray-design.md +0 -0
  223. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-05-moc-diagnose-archived-orphan-design.md +0 -0
  224. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-07-bm25-fresh-kb-logging-design.md +0 -0
  225. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-07-pi-prompt-capture-design.md +0 -0
  226. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-09-from-dict-non-dict-guard-design.md +0 -0
  227. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-09-nightly-test-failures-design.md +0 -0
  228. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-10-lightweight-install-embed-extra-design.md +0 -0
  229. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-10-skill-sync-399-overview-jfox-judge-design.md +0 -0
  230. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-14-json-schema-unify-design.md +0 -0
  231. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-14-wiki-link-self-link-design.md +0 -0
  232. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/superpowers/specs/2026-09-23-h1-strip-normalization-design.md +0 -0
  233. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/docs/troubleshooting.md +0 -0
  234. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jessica-jones-static-cable.md +0 -0
  235. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/__main__.py +0 -0
  236. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/add_dedup.py +0 -0
  237. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/__init__.py +0 -0
  238. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/cli.py +0 -0
  239. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/extractor.py +0 -0
  240. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/kimi_source.py +0 -0
  241. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/ledger.py +0 -0
  242. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/loop.py +0 -0
  243. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/runner.py +0 -0
  244. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/scanner.py +0 -0
  245. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/schedule.py +0 -0
  246. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/auto_summary/sources.py +0 -0
  247. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/backup/__init__.py +0 -0
  248. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/backup/cli.py +0 -0
  249. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/backup/loop.py +0 -0
  250. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/backup/manager.py +0 -0
  251. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/backup/schedule.py +0 -0
  252. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/bm25_index.py +0 -0
  253. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/bookshelf/__init__.py +0 -0
  254. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/bookshelf/cli.py +0 -0
  255. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/bookshelf/meta.py +0 -0
  256. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/bookshelf/store.py +0 -0
  257. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/candidates/__init__.py +0 -0
  258. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/candidates/cli.py +0 -0
  259. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/candidates/service.py +0 -0
  260. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/cli.py +0 -0
  261. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/config.py +0 -0
  262. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/daemon/__init__.py +0 -0
  263. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/daemon/__main__.py +0 -0
  264. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/daemon/client.py +0 -0
  265. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/daemon/process.py +0 -0
  266. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/daemon/server.py +0 -0
  267. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/dedup.py +0 -0
  268. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/dedup_lifecycle.py +0 -0
  269. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/embedding_backend.py +0 -0
  270. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/embedding_migration.py +0 -0
  271. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/formatters.py +0 -0
  272. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/fragment/__init__.py +0 -0
  273. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/fragment/cli.py +0 -0
  274. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/fragment/internal_sources.py +0 -0
  275. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/fragment/service.py +0 -0
  276. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/fragment/store.py +0 -0
  277. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/git_extractor.py +0 -0
  278. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/global_config.py +0 -0
  279. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/graph.py +0 -0
  280. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/indexer.py +0 -0
  281. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/kb_manager.py +0 -0
  282. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/moc/__init__.py +0 -0
  283. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/moc/cluster.py +0 -0
  284. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/moc/draft.py +0 -0
  285. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/moc/generate.py +0 -0
  286. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/model_downloader.py +0 -0
  287. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/performance.py +0 -0
  288. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/__init__.py +0 -0
  289. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/actions.py +0 -0
  290. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/cli.py +0 -0
  291. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/grounding.py +0 -0
  292. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/judge.py +0 -0
  293. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/lifecycle.py +0 -0
  294. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/runner.py +0 -0
  295. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/service.py +0 -0
  296. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/store.py +0 -0
  297. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/prompts/transcript.py +0 -0
  298. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/search_engine.py +0 -0
  299. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/template.py +0 -0
  300. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/template_cli.py +0 -0
  301. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/utils.py +0 -0
  302. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/jfox/vector_store.py +0 -0
  303. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/package.json +0 -0
  304. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/.claude-plugin/plugin.json +0 -0
  305. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/hooks/fragment-capture.sh +0 -0
  306. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/hooks/hooks.json +0 -0
  307. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/bookshelf/SKILL.md +0 -0
  308. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/ingest/SKILL.md +0 -0
  309. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/manage/SKILL.md +0 -0
  310. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/organize/SKILL.md +0 -0
  311. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/promote/SKILL.md +0 -0
  312. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/search/SKILL.md +0 -0
  313. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/session-summary/SKILL.md +0 -0
  314. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/session-to-permanent/SKILL.md +0 -0
  315. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/cc-plugin/skills/using-jfox/SKILL.md +0 -0
  316. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/README.md +0 -0
  317. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/kimi.plugin.json +0 -0
  318. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-admin/SKILL.md +0 -0
  319. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-auto-summary/SKILL.md +0 -0
  320. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-ingest/SKILL.md +0 -0
  321. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-manage/SKILL.md +0 -0
  322. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-organize/SKILL.md +0 -0
  323. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-promote/SKILL.md +0 -0
  324. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-search/SKILL.md +0 -0
  325. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-session-summary/SKILL.md +0 -0
  326. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-session-to-permanent/SKILL.md +0 -0
  327. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/jfox-template/SKILL.md +0 -0
  328. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/kimi-plugin/skills/using-jfox/SKILL.md +0 -0
  329. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/pi-plugin/README.md +0 -0
  330. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/pi-plugin/extensions/jfox-prompt-capture.ts +0 -0
  331. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/packages/pi-plugin/test/run-tests.ts +0 -0
  332. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/pytest.ini +0 -0
  333. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/run_full_test.ps1 +0 -0
  334. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/LOUVAIN_VERIFY.md +0 -0
  335. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/download-model-intranet.sh +0 -0
  336. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/enum_coverage.py +0 -0
  337. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/generate_docs.py +0 -0
  338. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/louvain_verify.py +0 -0
  339. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/nightly_test.sh +0 -0
  340. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/nightly_test_helpers.py +0 -0
  341. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/plugin_inventory.py +0 -0
  342. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/scripts/verify_lightweight_install.sh +0 -0
  343. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/README.md +0 -0
  344. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/kimi-cli/jfox-common/SKILL.md +0 -0
  345. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/kimi-cli/jfox-ingest/SKILL.md +0 -0
  346. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/kimi-cli/jfox-organize/SKILL.md +0 -0
  347. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/kimi-cli/jfox-search/SKILL.md +0 -0
  348. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/kimi-cli/jfox-session-summary/SKILL.md +0 -0
  349. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-bookshelf/SKILL.md +0 -0
  350. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-ci/SKILL.md +0 -0
  351. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-common/SKILL.md +0 -0
  352. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-ingest/SKILL.md +0 -0
  353. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-judge/SKILL.md +0 -0
  354. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-moc/SKILL.md +0 -0
  355. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-organize/SKILL.md +0 -0
  356. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-overview/SKILL.md +0 -0
  357. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-promote/SKILL.md +0 -0
  358. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-release/SKILL.md +0 -0
  359. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-release-all/SKILL.md +0 -0
  360. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-release-cc-plugin/SKILL.md +0 -0
  361. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-release-kimi-plugin/SKILL.md +0 -0
  362. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-search/SKILL.md +0 -0
  363. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-session-summary/SKILL.md +0 -0
  364. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/skills-recommend/pi/jfox-session-to-permanent/SKILL.md +0 -0
  365. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/COVERAGE_PLAN.md +0 -0
  366. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/MIGRATION.md +0 -0
  367. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/TESTS.md +0 -0
  368. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/conftest.py +0 -0
  369. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/fixtures/bulk_import_notes.json +0 -0
  370. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/__init__.py +0 -0
  371. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_auto_summary_kimi.py +0 -0
  372. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_candidate_promote_flow.py +0 -0
  373. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_cli_reference_generation.py +0 -0
  374. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_edit_roundtrip.py +0 -0
  375. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_fragment_capture_flow.py +0 -0
  376. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_index_rebuild_backlinks.py +0 -0
  377. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_links_edit_add.py +0 -0
  378. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_model_download.py +0 -0
  379. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_no_embed_degradation.py +0 -0
  380. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_plugin_inventory.py +0 -0
  381. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/integration/test_tag_filter_cli.py +0 -0
  382. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/performance/__init__.py +0 -0
  383. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/performance/test_performance.py +0 -0
  384. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_add_dedup_cli.py +0 -0
  385. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_advanced_features.py +0 -0
  386. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_cli_format.py +0 -0
  387. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_config_set_unit.py +0 -0
  388. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_config_unit.py +0 -0
  389. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_core_workflow.py +0 -0
  390. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_embedding_device.py +0 -0
  391. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_hybrid_search.py +0 -0
  392. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_integration.py +0 -0
  393. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_json_schema_contract.py +0 -0
  394. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_kb_current.py +0 -0
  395. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/test_suggest_links.py +0 -0
  396. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/__init__.py +0 -0
  397. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/bookshelf/__init__.py +0 -0
  398. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/bookshelf/conftest.py +0 -0
  399. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/bookshelf/test_cli.py +0 -0
  400. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/bookshelf/test_meta.py +0 -0
  401. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/bookshelf/test_store.py +0 -0
  402. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/conftest.py +0 -0
  403. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_add_backfill_links.py +0 -0
  404. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_add_dedup.py +0 -0
  405. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_archive.py +0 -0
  406. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_atomic_write.py +0 -0
  407. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_cli.py +0 -0
  408. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_config_sources.py +0 -0
  409. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_defaults.py +0 -0
  410. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_extractor.py +0 -0
  411. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_ledger.py +0 -0
  412. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_loop.py +0 -0
  413. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_runner.py +0 -0
  414. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_scanner.py +0 -0
  415. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_schedule.py +0 -0
  416. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_auto_summary_status.py +0 -0
  417. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_backup.py +0 -0
  418. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_bm25_batch.py +0 -0
  419. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_bm25_concurrency.py +0 -0
  420. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_bm25_fresh_kb_logging.py +0 -0
  421. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_candidates_migrated_cli.py +0 -0
  422. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_check.py +0 -0
  423. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_conftest_mock.py +0 -0
  424. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_content_file.py +0 -0
  425. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_daemon_cli.py +0 -0
  426. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_daemon_process.py +0 -0
  427. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_dedup_lifecycle.py +0 -0
  428. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_default_model_switch.py +0 -0
  429. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_delete_backlink_cleanup.py +0 -0
  430. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_delete_guard.py +0 -0
  431. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_edit.py +0 -0
  432. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_embed_availability.py +0 -0
  433. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_embedding_backend_daemon_only.py +0 -0
  434. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_embedding_local_load.py +0 -0
  435. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_embedding_migration.py +0 -0
  436. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_enum_coverage.py +0 -0
  437. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_format_unify.py +0 -0
  438. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_formatters.py +0 -0
  439. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_fragment_cli.py +0 -0
  440. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_fragment_config.py +0 -0
  441. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_fragment_hook.py +0 -0
  442. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_fragment_internal_sources.py +0 -0
  443. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_fragment_service.py +0 -0
  444. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_fragment_store.py +0 -0
  445. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_generate_docs.py +0 -0
  446. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_git_extractor.py +0 -0
  447. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_global_config.py +0 -0
  448. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_index_kb_param.py +0 -0
  449. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_indexer_clear_before_rebuild.py +0 -0
  450. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_indexer_verify.py +0 -0
  451. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_json_mode.py +0 -0
  452. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_kb_manager.py +0 -0
  453. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_kimi_extractor.py +0 -0
  454. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_kimi_plugin_skills.py +0 -0
  455. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_kimi_scanner.py +0 -0
  456. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_lazy_import.py +0 -0
  457. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_ledger_migration.py +0 -0
  458. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_list_notes_skip.py +0 -0
  459. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_logging_config.py +0 -0
  460. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_cli.py +0 -0
  461. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_cluster.py +0 -0
  462. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_create_cli.py +0 -0
  463. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_draft.py +0 -0
  464. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_generate.py +0 -0
  465. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_integration.py +0 -0
  466. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_member_cli.py +0 -0
  467. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_skill_docs.py +0 -0
  468. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_moc_update_cli.py +0 -0
  469. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_model_downloader.py +0 -0
  470. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_nightly_test_helpers.py +0 -0
  471. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_add_config.py +0 -0
  472. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_candidate_fields.py +0 -0
  473. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_candidate_filename.py +0 -0
  474. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_generator.py +0 -0
  475. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_index.py +0 -0
  476. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_lifecycle_hooks.py +0 -0
  477. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_promote.py +0 -0
  478. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_type_candidate.py +0 -0
  479. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_note_type_structure.py +0 -0
  480. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_plugin_inventory.py +0 -0
  481. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_actions.py +0 -0
  482. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_backfill.py +0 -0
  483. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_candidate.py +0 -0
  484. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_capture.py +0 -0
  485. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_cli.py +0 -0
  486. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_grounding.py +0 -0
  487. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_judge.py +0 -0
  488. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_retirement.py +0 -0
  489. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_runner.py +0 -0
  490. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_store.py +0 -0
  491. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_prompt_transcript.py +0 -0
  492. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_pyproject_embed_extra.py +0 -0
  493. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_rebuild_backlinks_impl.py +0 -0
  494. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_redirect.py +0 -0
  495. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_release_all_helper.py +0 -0
  496. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_release_cc_plugin_helper.py +0 -0
  497. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_release_helper.py +0 -0
  498. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_release_helper_verify.py +0 -0
  499. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_release_kimi_plugin_helper.py +0 -0
  500. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_runner_multi_source.py +0 -0
  501. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_scanner_list.py +0 -0
  502. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_search_engine_embed_warning.py +0 -0
  503. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_session_file_source.py +0 -0
  504. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_session_note.py +0 -0
  505. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_session_source.py +0 -0
  506. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_show.py +0 -0
  507. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_system_prompt_sections.py +0 -0
  508. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_tag_filter.py +0 -0
  509. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_template.py +0 -0
  510. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_template_cli.py +0 -0
  511. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_update.py +0 -0
  512. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_use_kb_env_var.py +0 -0
  513. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_using_jfox_skill.py +0 -0
  514. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_vector_store_clear.py +0 -0
  515. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_vector_store_dimension_warning.py +0 -0
  516. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_vector_store_embed_guard.py +0 -0
  517. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/unit/test_vector_store_embeddings.py +0 -0
  518. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/utils/__init__.py +0 -0
  519. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/utils/assertions.py +0 -0
  520. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/utils/jfox_cli.py +0 -0
  521. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/utils/note_generator.py +0 -0
  522. {jfox_cli-1.16.0 → jfox_cli-1.16.2}/tests/utils/temp_kb.py +0 -0
@@ -2,6 +2,34 @@
2
2
 
3
3
  All notable changes to jfox-cli will be documented in this file.
4
4
 
5
+ ## [1.16.2] - 2026-09-25
6
+
7
+ ### Fixes
8
+
9
+ - **note**: 加载笔记钉住真实磁盘路径,update_note 规范化写——消除同 ID 双文件 (#549) (#553)
10
+
11
+ [1.16.2]: https://github.com/zhuxixi/jfox/compare/v1.16.1...v1.16.2
12
+
13
+ ## [1.16.1] - 2026-09-24
14
+
15
+ ### Fixes
16
+
17
+ - **note_index**: 剥离改单遍合并正则——反引号包 HTML 注释不再吞后续 wiki link (#548) (#550)
18
+
19
+ ### Changes
20
+
21
+ - **claude.md**: batch refresh — fold in 6 pending auto/claude-md PRs (#520/#524/#527/#532/#540/#545) (#546)
22
+
23
+ [1.16.1]: https://github.com/zhuxixi/jfox/compare/v1.16.0...v1.16.1
24
+
25
+ ## [Unreleased]
26
+
27
+ ### Fixes
28
+
29
+ - **note**: 加载的笔记钉住真实磁盘路径——文件名与当前字段分家时,补 backlink / rebuild --backlinks / MOC 成员回填不再写出同 ID 双文件,`show`/`delete` 也能正确读写该笔记;`update_note` 改为显式规范化写并在成功后重钉路径 (#549)
30
+
31
+ - **note_index**: 剥离改单遍合并正则——反引号包 HTML 注释不再吞后续 wiki link (#548) (#550)
32
+
5
33
  ## [1.16.0] - 2026-09-23
6
34
 
7
35
  ### 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.5.
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: jfox-cli
3
- Version: 1.16.0
3
+ Version: 1.16.2
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
@@ -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 留痕 |
@@ -0,0 +1,305 @@
1
+ # #549 同 ID 双文件修复 实现计划
2
+
3
+ > **For agentic workers:** Steps use checkbox (`- [ ]`) syntax to track progress. Follow instructions exactly.
4
+
5
+ **Spec:** `docs/superpowers/specs/2026-09-24-issue-549-twin-files-design.md`(commit 47b236c)
6
+
7
+ **Work from:** `/home/elling/git-repo/github/jfox/.pi/worktrees/issue-549-stale-name-twin-files`(所有路径以此为根;禁止碰主 checkout)
8
+
9
+ **技术摘要:** 路径语义两分法——`from_markdown` 钉住真实路径(`save_note` 就地写)+ `update_note` 写盘目标改用 `expected_filepath`(规范化写 + 成功后重钉 pin)。
10
+
11
+ ## 验收归属(spec 矩阵 → 任务)
12
+
13
+ | 验收 ID | 归属 |
14
+ |---------|------|
15
+ | A1/A2(路径纯函数 + 钉路径) | Task 1 |
16
+ | A3(update_note 自愈 + 重钉 pin) | Task 1 |
17
+ | A9(护栏:改名/移目录保持绿) | Task 1 |
18
+ | A4–A8(CLI 症状层) | Task 2 |
19
+ | CHANGELOG/注释交付物 | Task 3 |
20
+ | U1(真实库受控演练) | 合并后单独人工项,非代码任务 |
21
+
22
+ ## 前置事实(实现者必读,违反即返工)
23
+
24
+ 1. **原子性约束**:`models.py` 的钉路径与 `note.py` 的 `update_note` 调整**必须同任务同 commit 落地**。中间态(只钉路径)会让 `tests/unit/test_edit.py:72-82`(改标题→改名)与 `:373-390`(改 type→跨目录)挂掉(E2b 已实证)。
25
+ 2. **契约边界**:改 title/topic/type 的意图只走 `update_note`;`save_note` 是就地写。不要给 `save_note` 加任何「找旧文件/改名」逻辑——本修复不靠它。
26
+ 3. **改动面**:只允许碰 `jfox/models.py`、`jfox/note.py`、两个测试文件、`CHANGELOG.md`。不碰 `moc/`、`redirect.py`、其余 save_note 站点(钉路径后它们自动受益)。
27
+ 4. **测试命名**:文件/用例名避开子串 `search|semantic|embedding|vector|query|suggest`;用例标题全局唯一(#483 闸门)。本计划的文件名已满足:`test_note_path_rules.py`、`test_stale_name_single_file.py`。
28
+ 5. **夹具手法**:发散名 = 只 rename 文件(保留 id 前缀),不改 frontmatter——`cli_fast` 每条命令独立子进程,索引按盘重建,发散笔记可被正常发现/解析。
29
+ 6. **#483 之后 add permanent 有 dedup 闸门**:测试标题彼此差异要大,别用近似标题。
30
+
31
+ ---
32
+
33
+ ## Task 1: 路径语义核心(models.py + note.py + A1/A2/A3/A9)
34
+
35
+ **Files:**
36
+
37
+ - Create: `tests/unit/test_note_path_rules.py`
38
+ - Create: `tests/integration/test_stale_name_single_file.py`(先只放 A3 两个用例)
39
+ - Modify: `jfox/models.py`
40
+ - Modify: `jfox/note.py`
41
+
42
+ - [ ] **Step 1: 写失败测试**
43
+
44
+ `tests/unit/test_note_path_rules.py`(A1/A2,纯函数层,无需 KB 写入):
45
+
46
+ ```python
47
+ class TestExpectedFilepath:
48
+ def test_permanent_uses_title_slug(self) # A1:expected == config.notes_dir/"permanent"/filename
49
+ def test_session_uses_topic(self) # A1
50
+ def test_session_without_topic_falls_back_to_title(self) # A1
51
+ def test_fleeting_uses_dash_form(self) # A1:{id[:8]}-{id[8:]}.md
52
+ def test_expected_filepath_ignores_pin(self) # A1:set_filepath 后 expected 不变、filepath 变
53
+
54
+ class TestFromMarkdownPin:
55
+ def test_with_filepath_pins_it(self) # A2:note.filepath == 传入路径
56
+ def test_without_filepath_stays_unpinned(self) # A2:note.filepath == expected_filepath
57
+ ```
58
+
59
+ `tests/integration/test_stale_name_single_file.py`(A3,先行两个用例;发散名 helper 共用):
60
+
61
+ ```python
62
+ def _diverge(filepath: str) -> Path:
63
+ """只 rename 文件制造发散名(保留 id 前缀),模拟外部改标题未同步改名"""
64
+ p = Path(filepath)
65
+ d = p.with_name(f"{p.stem}-diverged.md")
66
+ p.rename(d)
67
+ return d
68
+
69
+
70
+ def _files_for(dir_path: Path, nid: str) -> list:
71
+ return sorted(dir_path.glob(f"{nid}*.md"))
72
+
73
+
74
+ class TestUpdateSelfHeal:
75
+ def test_edit_title_on_diverged_name_canonicalizes(self, cli_fast):
76
+ """A3:发散名笔记经 edit --title 后规范化为规则名,全程单文件"""
77
+ # add permanent → 从 add 的 JSON 取 note.filepath → _diverge →
78
+ # cli_fast.edit(id, title="全新标题X") →
79
+ # 断言 _files_for 单文件、文件名含新标题 slug、旧发散名不存在
80
+
81
+ def test_second_save_after_update_no_resurrect(self, temp_kb_registered):
82
+ """A3:同对象 update_note 后再 save_note,不复活旧路径(重钉 pin 契约)"""
83
+ # 复用 test_delete_backlink_cleanup.py 的 temp_kb_registered + use_kb 模式:
84
+ # load → note.update_note(改标题)→ 对同对象 note.save_note →
85
+ # 断言旧路径文件未被重新创建,且规则名文件唯一
86
+ ```
87
+
88
+ (`temp_kb_registered` 参照 `tests/unit/test_delete_backlink_cleanup.py` 的用法;若该 fixture 名不匹配,用 conftest 中已有的等价临时 KB 上下文。)
89
+
90
+ - [ ] **Step 2: 运行确认失败**
91
+
92
+ ```bash
93
+ uv run pytest tests/unit/test_note_path_rules.py tests/integration/test_stale_name_single_file.py -x -q
94
+ ```
95
+
96
+ 预期:`expected_filepath` 不存在(AttributeError)/ 钉路径未生效 → FAIL。只确认 RED,不修。
97
+
98
+ - [ ] **Step 3: 实现 `jfox/models.py`**
99
+
100
+ ① 新增 property(放 `filepath` 旁,注释为交付物):
101
+
102
+ ```python
103
+ @property
104
+ def expected_filepath(self) -> Path:
105
+ """按当前字段现算的规则路径(type 目录 + filename),不看 _filepath pin。
106
+
107
+ #549 两分法的另一半:update_note(规范化写)以本属性为写盘目标;
108
+ filepath 在笔记从磁盘加载时被钉住为真实路径(就地写)。
109
+ 用 note_obj.filepath 代替本属性的已知后果:钉路径后改名判据
110
+ `old != note.filepath` 恒假,edit --title / 改 type 不再改名移动
111
+ (tests/unit/test_edit.py:72-82、:373-390 必挂)。
112
+ """
113
+ from .config import config
114
+
115
+ return config.notes_dir / self.type.value / self.filename
116
+ ```
117
+
118
+ ② `from_markdown`:把 `return cls(...)` 改为先存变量再钉路径(注释为交付物):
119
+
120
+ ```python
121
+ note = cls(
122
+ ... # 现有参数不动
123
+ )
124
+ # #549:钉住加载来源的真实磁盘路径。此后 note.filepath 返回真实路径,
125
+ # save_note(就地写)写回原文件——文件名与当前字段分家时也不会在规则名上
126
+ # 另写同 id 双文件。需要「按当前字段重新定址」的操作(改标题/改 type)
127
+ # 请走 note.update_note,其写盘目标用 expected_filepath。
128
+ if filepath is not None:
129
+ note._filepath = Path(filepath)
130
+ return note
131
+ ```
132
+
133
+ ③ `filepath` property 的 docstring 补一句「加载的笔记此处返回真实磁盘路径;规则路径请用 expected_filepath」。
134
+
135
+ - [ ] **Step 4: 实现 `jfox/note.py`**
136
+
137
+ ① `update_note` 写盘段(原 `_atomic_write(note_obj.filepath, ...)` 处):
138
+
139
+ ```python
140
+ # 规范化写(#549):目标路径按当前字段现算,不看加载 pin。
141
+ target = note_obj.expected_filepath
142
+ _atomic_write(target, note_obj.to_markdown())
143
+
144
+ if old_filepath != target and old_filepath.exists():
145
+ old_filepath.unlink()
146
+ logger.info(f"Renamed note file: {old_filepath} -> {target}")
147
+
148
+ # #549:写盘成功后把 pin 重钉到刚写入的路径——否则同一对象随后的
149
+ # save_note(就地写)会按陈旧 pin 写回旧路径、复活同 id 双文件。
150
+ note_obj.set_filepath(target)
151
+ ```
152
+
153
+ ② `save_note` docstring 补契约边界(交付物):
154
+
155
+ ```
156
+ 注意(#549):写盘目标是 note.filepath——对从磁盘加载的笔记即「就地写回
157
+ 加载路径」;就地写不保证文件名随字段变化。改 title/topic/type 的意图请用
158
+ update_note(规范化写:按当前字段现算目标并删除旧文件)。
159
+ ```
160
+
161
+ - [ ] **Step 5: 运行确认通过**
162
+
163
+ ```bash
164
+ uv run pytest tests/unit/test_note_path_rules.py tests/integration/test_stale_name_single_file.py -q
165
+ ```
166
+
167
+ 预期全绿。
168
+
169
+ - [ ] **Step 6: 护栏回归(A9)**
170
+
171
+ ```bash
172
+ uv run pytest tests/unit/test_edit.py -q
173
+ ```
174
+
175
+ 预期全绿(改标题改名、改 type 跨目录不受影响)。
176
+
177
+ - [ ] **Step 7: 快速回归**
178
+
179
+ ```bash
180
+ uv run pytest tests/unit -m "not embedding and not slow" -q
181
+ ```
182
+
183
+ - [ ] **Step 8: commit**
184
+
185
+ ```bash
186
+ git add jfox/models.py jfox/note.py tests/unit/test_note_path_rules.py tests/integration/test_stale_name_single_file.py
187
+ git commit -m "fix(note): 加载笔记钉住真实路径,update_note 规范化写+重钉 pin——消除同 ID 双文件(#549 A1-A3/A9)"
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Task 2: CLI 症状层集成测试(A4–A8)
193
+
194
+ **Files:**
195
+
196
+ - Modify: `tests/integration/test_stale_name_single_file.py`
197
+
198
+ - [ ] **Step 1: 补五个测试类(TDD:先写先跑,应在 Task 1 的实现上直接转绿——若红说明 Task 1 有漏)**
199
+
200
+ ```python
201
+ class TestAddBackfill:
202
+ def test_add_link_to_diverged_target_keeps_single_file(self, cli_fast):
203
+ """A4:add 链接发散名目标 → 单文件 + backlinks 落真实文件"""
204
+ # A = add permanent(标题「回填目标甲」)→ _diverge →
205
+ # B = add「链向 [[回填目标甲]]」→
206
+ # 断言 _files_for(A) 单文件(发散名那份)、A 文件 backlinks 含 B.id
207
+
208
+ class TestEditBackfill:
209
+ def test_edit_add_link_diverged_target_keeps_single_file(self, cli_fast):
210
+ """A5:edit 新增链接 → 单文件 + backlinks 落位"""
211
+ def test_edit_remove_link_diverged_target_keeps_single_file(self, cli_fast):
212
+ """A5:edit 移除链接 → backlinks 移除 + 仍单文件"""
213
+
214
+ class TestRebuildBacklinks:
215
+ def test_rebuild_touches_diverged_note_in_place(self, cli_fast):
216
+ """A6:rebuild --backlinks 触及发散名笔记时单文件"""
217
+ # 造 links/backlinks 必变化:直接改发散文件 frontmatter,给 backlinks 加一个假 id
218
+ # cli_fast.index_rebuild(backlinks=True) →
219
+ # 断言单文件、backlinks 被重算(假 id 消失)
220
+
221
+ class TestShowDelete:
222
+ def test_show_reads_diverged_note(self, cli_fast):
223
+ """A7:show 发散名笔记 success=true(此前报 Errno 2)"""
224
+ def test_delete_removes_real_file(self, cli_fast):
225
+ """A7:delete --force 删真实文件(无入链前置)→ glob 为空"""
226
+
227
+ class TestMocMemberBackfill:
228
+ def test_moc_backfill_diverged_member_keeps_single_file(self, temp_kb_registered):
229
+ """A8:moc 成员回填(python 级 backfill_moc_backlinks)→ 单文件"""
230
+ # 构造 structure Note(或 CLI add --type structure)+ 发散名成员
231
+ # 调 jfox.moc.generate.backfill_moc_backlinks(moc_note, [member_id], cfg)
232
+ # 断言单文件 + backlinks 含 moc.id
233
+ ```
234
+
235
+ - [ ] **Step 2: 运行该文件全量**
236
+
237
+ ```bash
238
+ uv run pytest tests/integration/test_stale_name_single_file.py -q
239
+ ```
240
+
241
+ - [ ] **Step 3: 相关既有集成测试回归**
242
+
243
+ ```bash
244
+ uv run pytest tests/integration/test_links_edit_add.py tests/integration/test_index_rebuild_backlinks.py tests/integration/test_edit_roundtrip.py tests/unit/test_delete_backlink_cleanup.py tests/unit/test_note_promote.py -q
245
+ ```
246
+
247
+ 预期全绿(同族回填/晋升链路未受影响)。
248
+
249
+ - [ ] **Step 4: commit**
250
+
251
+ ```bash
252
+ git add tests/integration/test_stale_name_single_file.py
253
+ git commit -m "test(links): 发散名笔记 CLI 症状层集成测试——add/edit/rebuild/show+delete/moc 均单文件(#549 A4-A8)"
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Task 3: CHANGELOG + 注释交付物复核 + 全量回归
259
+
260
+ **Files:**
261
+
262
+ - Modify: `CHANGELOG.md`
263
+
264
+ - [ ] **Step 1: `## [Unreleased]` 的 `### Fixed` 下加条目**
265
+
266
+ ```markdown
267
+ - links: 加载的笔记钉住真实磁盘路径——文件名与当前字段分家时,补 backlink / rebuild --backlinks / MOC 成员回填不再写出同 ID 双文件,`show`/`delete` 也能正确读写该笔记;`update_note` 改为显式规范化写并在成功后重钉路径(#549)
268
+ ```
269
+
270
+ - [ ] **Step 2: 注释交付物复核(对照 spec §7)**:`filepath` property、`from_markdown`、`update_note` 三处注释齐(两分法、E2b 后果、重钉原因);不齐则补。
271
+
272
+ - [ ] **Step 3: markdownlint**
273
+
274
+ ```bash
275
+ npx --yes markdownlint-cli2@0.23.2 "CHANGELOG.md"
276
+ ```
277
+
278
+ - [ ] **Step 4: 全量快速回归(本地 CR 前置)**
279
+
280
+ ```bash
281
+ uv run pytest tests/ -m "not embedding and not slow" -q
282
+ ```
283
+
284
+ - [ ] **Step 5: commit**
285
+
286
+ ```bash
287
+ git add CHANGELOG.md
288
+ git commit -m "docs(changelog): #549 同 ID 双文件修复条目"
289
+ ```
290
+
291
+ ---
292
+
293
+ ## 完成标准
294
+
295
+ - A1–A9 全部有对应测试且全绿;U1 留待合并后用户点头执行(spec §5)。
296
+ - 快速套件 `tests/ -m "not embedding and not slow"` 全绿。
297
+ - 分支只含 4 个 commit(spec / 核心修复 / 症状层测试 / changelog),主 checkout 零改动。
298
+
299
+ ---
300
+
301
+ ## 执行偏差记录(终审补记)
302
+
303
+ 1. **测试文件名更名**:spec 中的 `tests/unit/test_note_path_semantics.py` 实际落地为 `test_note_path_rules.py`——#483 命名约束要求避开子串 `semantic`(spec 已同步修订)。
304
+ 2. **分支为 6 个 commit 而非 4 个**:Task 1 的 lint fix wave(ruff/black)amend 进核心 commit;第 5 个 commit `a5ed229` 为终审挂账的注释债清理(`redirect.py`、`moc/cli.py`、`test_moc_member_commands.py` 纯注释/docstring——reviewer 指出「from_markdown 不回填 `_filepath`」在修复后已成假命题),第 6 个为本修订。前置事实 3 的「不碰 moc/、redirect.py」原指行为代码,注释债清理经 reviewer 建议纳入。
305
+ 3. **plan 的用例骨架微调**:`temp_kb_registered` 实为 `tests/utils/temp_kb.py` 的 context manager(非 fixture),A3-2/A8 按计划备注改用 `use_kb(kb_name)` + python 级 note API 模式。