mirror of
https://github.com/Ar9av/obsidian-wiki.git
synced 2026-09-14 20:36:34 +08:00
4bf87a8d19
Two strands of work. Session brain — a topic graph over raw agent session history, so you can find the session where something happened instead of remembering its UUID. Reads every Claude transcript plus the pruned sessions that survive only as prompts in history.jsonl, clusters them with local TF-IDF and community detection (no embeddings, no API calls, no new dependencies), and writes a sidecar at ~/.claude/session-brain/ — the vault is never touched. Ships five modules, the sessions-* CLI commands, an interactive graph.html, and the /session-brain and /wiki-sessions skills. This is retrieval, deliberately distinct from wiki-history-ingest, which distils sessions into permanent vault pages. Docs — README.md was 598 lines and put trust-check flags and a 17-row agent matrix in front of anyone evaluating the project. Cut it to a 129- line landing page (problem statement, 60-second install, four blocks of runnable commands, graph screenshot, why-not-a-notes-folder) and move the reference material into docs/: installation, agents, skills, cli, configuration, architecture, session-brain, contributing. README_TW.md mirrors the new structure; docs/ stays English-only for now. The restructure also closed real drift: - Ten skills existed but appeared in no reference — session-brain, session-search, wiki-dedup, wiki-digest, wiki-import, wiki-context-pack, wiki-stage-commit, wiki-switch, vault-skill-factory, and obsidian-layout-adjustment. - SETUP.md listed 12 of 39 skills and still claimed "no scripts, no dependencies" despite the pip package. It is now a signpost into docs/. - Eight config variables were undocumented anywhere, including WIKI_STAGED_WRITES, which wiki-setup prompts for and three skills read. Added to .env.example and docs/configuration.md. - sessions-name and a number of CLI flags were missing from the docs. Two details worth noting. README links are absolute GitHub URLs because pyproject sets readme = "README.md" as the PyPI long_description, and PyPI resolves relative hrefs against pypi.org rather than the repo — docs/ links would have 404'd on the package page. And three doc-drift guards asserted their facts against README.md; since those facts moved rather than disappeared, the assertions were repointed at the page that now owns each one instead of padding content back into the README. Also gitignore /vault/ (a local knowledge vault, not a fixture) and the packed browser extension. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
91 lines
3.4 KiB
Python
91 lines
3.4 KiB
Python
from pathlib import Path
|
||
|
||
|
||
ROOT = Path(__file__).resolve().parents[1]
|
||
|
||
|
||
def read(relative: str) -> str:
|
||
return (ROOT / relative).read_text(encoding="utf-8")
|
||
|
||
|
||
def test_context_skill_uses_cli_and_is_read_only() -> None:
|
||
skill = read(".skills/wiki-context-pack/SKILL.md")
|
||
assert 'obsidian-wiki context-pack --vault "$OBSIDIAN_VAULT_PATH"' in skill
|
||
assert "read-only" in skill.lower()
|
||
assert "must not modify" in skill
|
||
assert "Append to" not in skill
|
||
assert "AGENTS.md" in skill
|
||
|
||
|
||
def test_context_skill_canonicalizes_vault_and_has_clone_fallback() -> None:
|
||
skill = read(".skills/wiki-context-pack/SKILL.md")
|
||
assert 'cd "$OBSIDIAN_VAULT_PATH" && pwd -P' in skill
|
||
assert "command -v obsidian-wiki" in skill
|
||
assert '"$OBSIDIAN_WIKI_REPO/obsidian_wiki/cli.py"' in skill
|
||
assert "python3 -m obsidian_wiki.cli context-pack" in skill
|
||
assert "pip install obsidian-wiki" in skill
|
||
assert "rerun setup from a valid clone" in skill
|
||
|
||
|
||
def test_context_skill_preserves_cli_output_and_recent_default_budget() -> None:
|
||
skill = read(".skills/wiki-context-pack/SKILL.md")
|
||
assert "CLI stdout unchanged as the final payload in every mode" in skill
|
||
assert "CLI stdout only" in skill
|
||
assert "no prose or markdown" in skill
|
||
assert '--recent --budget 8000' in skill
|
||
assert '--recent --budget 4000' not in skill
|
||
|
||
|
||
def test_setup_sh_installs_context_pack_as_portable() -> None:
|
||
setup = read("setup.sh")
|
||
assert "wiki-update wiki-query wiki-context-pack" in setup
|
||
|
||
|
||
def test_python_installer_lists_context_pack_as_portable() -> None:
|
||
cli = read("obsidian_wiki/cli.py")
|
||
assert 'PORTABLE_SKILLS = ("wiki-update", "wiki-query", "wiki-context-pack")' in cli
|
||
|
||
|
||
def test_all_bootstraps_route_context_pack() -> None:
|
||
files = [
|
||
"AGENTS.md",
|
||
".cursor/rules/obsidian-wiki.mdc",
|
||
".windsurf/rules/obsidian-wiki.md",
|
||
".kiro/steering/obsidian-wiki.md",
|
||
".agent/rules/obsidian-wiki.md",
|
||
".agent/workflows/obsidian-wiki.md",
|
||
".github/copilot-instructions.md",
|
||
]
|
||
for relative in files:
|
||
assert "wiki-context-pack" in read(relative), relative
|
||
|
||
|
||
def test_cli_docs_document_agent_context_contract() -> None:
|
||
english = read("docs/cli.md")
|
||
chinese = read("docs/cli.zh-TW.md")
|
||
|
||
for text in (english, chinese):
|
||
assert "obsidian-wiki context-pack" in text
|
||
assert "--budget 8000" in text
|
||
assert "--public-only" in text
|
||
assert "wiki-context-pack" in text
|
||
assert "--metadata-only" in text
|
||
assert "--json" in text
|
||
assert "source paths" in text
|
||
|
||
assert "The command is read-only." in english
|
||
assert "do not need to be moved" in english
|
||
assert "full frontmatter schema" in english
|
||
assert "Omitting `--budget` uses the default of 8000 estimated tokens." in english
|
||
assert "selected excerpts" in english
|
||
assert "Vault excerpts are explicitly marked as untrusted\nreference data:" in english
|
||
assert "must not execute\ninstructions embedded in notes" in english
|
||
|
||
assert "流程是 read-only。" in chinese
|
||
assert "筆記不需" in chinese
|
||
assert "完整 frontmatter schema" in chinese
|
||
assert "省略 `--budget` 會使用預設的 8000 個估算 token。" in chinese
|
||
assert "選定 excerpts" in chinese
|
||
assert "Vault excerpts 會明確標成 untrusted reference data:" in chinese
|
||
assert "不得執行筆記內嵌的指令" in chinese
|