obsidian-knowledge 3.19.0__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.
- obsidian_knowledge-3.19.0/.claude/hookify.require-plugin-version-bump.md +25 -0
- obsidian_knowledge-3.19.0/.claude-plugin/marketplace.json +17 -0
- obsidian_knowledge-3.19.0/.claude-plugin/plugin.json +79 -0
- obsidian_knowledge-3.19.0/.github/workflows/publish.yml +24 -0
- obsidian_knowledge-3.19.0/.gitignore +7 -0
- obsidian_knowledge-3.19.0/LICENSE +22 -0
- obsidian_knowledge-3.19.0/PKG-INFO +10 -0
- obsidian_knowledge-3.19.0/README.md +323 -0
- obsidian_knowledge-3.19.0/commands/improve-harness.md +11 -0
- obsidian_knowledge-3.19.0/commands/scan-secrets.md +29 -0
- obsidian_knowledge-3.19.0/commands/vault-search.md +39 -0
- obsidian_knowledge-3.19.0/docs/TODO.md +31 -0
- obsidian_knowledge-3.19.0/docs/superpowers/plans/2026-04-25-improve-harness-implementation.md +1608 -0
- obsidian_knowledge-3.19.0/docs/superpowers/plans/2026-05-12-changelog-reform.md +804 -0
- obsidian_knowledge-3.19.0/docs/superpowers/specs/2026-04-25-improve-harness-design.md +331 -0
- obsidian_knowledge-3.19.0/docs/superpowers/specs/2026-05-12-changelog-reform-design.md +103 -0
- obsidian_knowledge-3.19.0/hermes_plugin/__init__.py +302 -0
- obsidian_knowledge-3.19.0/hermes_plugin/plugin.yaml +8 -0
- obsidian_knowledge-3.19.0/hooks/doctor.py +175 -0
- obsidian_knowledge-3.19.0/hooks/enforce-conventions.py +120 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/__init__.py +1 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/patterns.py +131 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/recall_init_lib.py +34 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/reflect_counter.py +35 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/repo_memory.py +139 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/stop_hook.py +50 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/transcript.py +38 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/vault_config.py +49 -0
- obsidian_knowledge-3.19.0/hooks/hookslib/vault_policy.py +57 -0
- obsidian_knowledge-3.19.0/hooks/nudge-index-sync.py +97 -0
- obsidian_knowledge-3.19.0/hooks/protect-vault.py +650 -0
- obsidian_knowledge-3.19.0/hooks/recall-init.py +73 -0
- obsidian_knowledge-3.19.0/hooks/reflect-nudge.py +54 -0
- obsidian_knowledge-3.19.0/hooks/remind-convos.py +55 -0
- obsidian_knowledge-3.19.0/hooks/remind-convos.sh +6 -0
- obsidian_knowledge-3.19.0/hooks/scan-vault-secrets.py +484 -0
- obsidian_knowledge-3.19.0/hooks/update-changelog.py +42 -0
- obsidian_knowledge-3.19.0/hooks/update-changelog.sh +6 -0
- obsidian_knowledge-3.19.0/lib/__init__.py +0 -0
- obsidian_knowledge-3.19.0/lib/vault_index/__init__.py +19 -0
- obsidian_knowledge-3.19.0/lib/vault_index/cli.py +217 -0
- obsidian_knowledge-3.19.0/lib/vault_index/config.py +44 -0
- obsidian_knowledge-3.19.0/lib/vault_index/filters.py +86 -0
- obsidian_knowledge-3.19.0/lib/vault_index/indexer.py +398 -0
- obsidian_knowledge-3.19.0/lib/vault_index/primer.py +58 -0
- obsidian_knowledge-3.19.0/pyproject.toml +27 -0
- obsidian_knowledge-3.19.0/scripts/build_memory_indexes.py +87 -0
- obsidian_knowledge-3.19.0/scripts/local_smoke_test.py +89 -0
- obsidian_knowledge-3.19.0/scripts/migrate_changelog.py +134 -0
- obsidian_knowledge-3.19.0/scripts/migrate_claude_memory.py +226 -0
- obsidian_knowledge-3.19.0/skills/deploy-harness/SKILL.md +70 -0
- obsidian_knowledge-3.19.0/skills/improve-harness/SKILL.md +69 -0
- obsidian_knowledge-3.19.0/skills/improve-harness/conventions.md +38 -0
- obsidian_knowledge-3.19.0/skills/improve-harness/phases.md +122 -0
- obsidian_knowledge-3.19.0/skills/improve-harness/templates.md +45 -0
- obsidian_knowledge-3.19.0/skills/obsidian-knowledge/SKILL.md +105 -0
- obsidian_knowledge-3.19.0/skills/remember-conversations/SKILL.md +191 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/SKILL.md +116 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/convention-sweep.py +122 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/filter-unresolved-links.py +113 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/find-open-questions.py +106 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/fix-stacked-frontmatter.py +156 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/lib/broken-links.md +48 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/lib/index-format.md +54 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/lib/note-types.md +38 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/lib/rename-files.md +33 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/lib/stacked-frontmatter.md +77 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/lib/state-files.md +43 -0
- obsidian_knowledge-3.19.0/skills/vault-organizer/vault-audit.py +248 -0
- obsidian_knowledge-3.19.0/tests/__init__.py +0 -0
- obsidian_knowledge-3.19.0/tests/conftest.py +83 -0
- obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/.claude/obsidian-knowledge.yaml +12 -0
- obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/Inbox/random.md +2 -0
- obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/Journal/diary.md +2 -0
- obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/wiki/python.md +2 -0
- obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/wiki/rust.md +2 -0
- obsidian_knowledge-3.19.0/tests/fixtures/transcript_new_file_no_index.jsonl +1 -0
- obsidian_knowledge-3.19.0/tests/fixtures/transcript_new_file_with_index.jsonl +2 -0
- obsidian_knowledge-3.19.0/tests/test_cli.py +117 -0
- obsidian_knowledge-3.19.0/tests/test_config.py +67 -0
- obsidian_knowledge-3.19.0/tests/test_doctor.py +81 -0
- obsidian_knowledge-3.19.0/tests/test_enforce_conventions.py +151 -0
- obsidian_knowledge-3.19.0/tests/test_filters.py +129 -0
- obsidian_knowledge-3.19.0/tests/test_hermes_provider.py +176 -0
- obsidian_knowledge-3.19.0/tests/test_indexer.py +213 -0
- obsidian_knowledge-3.19.0/tests/test_migrate_changelog.py +209 -0
- obsidian_knowledge-3.19.0/tests/test_nudge_index_sync.py +68 -0
- obsidian_knowledge-3.19.0/tests/test_patterns.py +163 -0
- obsidian_knowledge-3.19.0/tests/test_primer.py +19 -0
- obsidian_knowledge-3.19.0/tests/test_protect_vault_memory_redirect.py +108 -0
- obsidian_knowledge-3.19.0/tests/test_recall_init.py +70 -0
- obsidian_knowledge-3.19.0/tests/test_recall_init_lib.py +28 -0
- obsidian_knowledge-3.19.0/tests/test_reflect_counter.py +33 -0
- obsidian_knowledge-3.19.0/tests/test_reflect_nudge.py +72 -0
- obsidian_knowledge-3.19.0/tests/test_repo_memory.py +106 -0
- obsidian_knowledge-3.19.0/tests/test_scan_vault_secrets.py +137 -0
- obsidian_knowledge-3.19.0/tests/test_transcript.py +44 -0
- obsidian_knowledge-3.19.0/uv.lock +1846 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: require-plugin-version-bump
|
|
3
|
+
enabled: true
|
|
4
|
+
event: bash
|
|
5
|
+
action: block
|
|
6
|
+
pattern: obsidian-knowledge.*git\s+commit
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**Version bump required before committing to obsidian-knowledge plugin.**
|
|
10
|
+
|
|
11
|
+
Before this commit proceeds, verify that version numbers have been bumped. Check staged changes:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd /home/ricardo/src/PERSONAL/obsidian-knowledge && git diff --cached --name-only
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
At least these files must be in the staged changes with an updated version:
|
|
18
|
+
- `.claude-plugin/plugin.json`
|
|
19
|
+
- `.claude-plugin/marketplace.json`
|
|
20
|
+
|
|
21
|
+
And if any SKILL.md was modified, bump its version too:
|
|
22
|
+
- `skills/vault-organizer/SKILL.md`
|
|
23
|
+
- `skills/remember-conversations/SKILL.md`
|
|
24
|
+
|
|
25
|
+
If versions are already bumped, re-run the commit. If not, bump them first, stage, then commit.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "obsidian-knowledge",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Ricardo Decal"
|
|
5
|
+
},
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "Skills, hooks, and conventions for maintaining Obsidian knowledge base vaults"
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "obsidian-knowledge",
|
|
12
|
+
"source": "./",
|
|
13
|
+
"description": "Skills, hooks, and conventions for maintaining Obsidian knowledge base vaults",
|
|
14
|
+
"version": "3.17.1"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "obsidian-knowledge",
|
|
3
|
+
"version": "3.19.0",
|
|
4
|
+
"description": "Self-evolving Claude Code plugin that manages an Obsidian knowledge vault: capture, organize, index, garden — plus a meta-skill that improves the harness itself",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Ricardo Decal"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"keywords": ["obsidian", "knowledge-base", "vault", "organization"],
|
|
10
|
+
"hooks": {
|
|
11
|
+
"PreToolUse": [
|
|
12
|
+
{
|
|
13
|
+
"matcher": "Bash|Write|Edit",
|
|
14
|
+
"hooks": [
|
|
15
|
+
{
|
|
16
|
+
"type": "command",
|
|
17
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/protect-vault.py"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"matcher": "Write|Edit",
|
|
23
|
+
"hooks": [
|
|
24
|
+
{
|
|
25
|
+
"type": "command",
|
|
26
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/enforce-conventions.py"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"Stop": [
|
|
32
|
+
{
|
|
33
|
+
"hooks": [
|
|
34
|
+
{
|
|
35
|
+
"type": "command",
|
|
36
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/update-changelog.py"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "command",
|
|
40
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/remind-convos.py"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "command",
|
|
44
|
+
"command": "uv run --script ${CLAUDE_PLUGIN_ROOT}/hooks/scan-vault-secrets.py"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/nudge-index-sync.py"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"SessionStart": [
|
|
54
|
+
{
|
|
55
|
+
"hooks": [
|
|
56
|
+
{
|
|
57
|
+
"type": "command",
|
|
58
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/recall-init.py"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "command",
|
|
62
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/doctor.py"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"PostToolUse": [
|
|
68
|
+
{
|
|
69
|
+
"matcher": "Bash",
|
|
70
|
+
"hooks": [
|
|
71
|
+
{
|
|
72
|
+
"type": "command",
|
|
73
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/reflect-nudge.py"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write # required for OIDC trusted publishing
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: astral-sh/setup-uv@v5
|
|
19
|
+
|
|
20
|
+
- name: Build
|
|
21
|
+
run: uv build
|
|
22
|
+
|
|
23
|
+
- name: Publish
|
|
24
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ricardo Decal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: obsidian-knowledge
|
|
3
|
+
Version: 3.19.0
|
|
4
|
+
Summary: Obsidian vault knowledge integration for Claude Code and Hermes Agent CLI
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: memweave>=0.1
|
|
8
|
+
Requires-Dist: platformdirs>=4.9.6
|
|
9
|
+
Requires-Dist: pydantic>=2.0
|
|
10
|
+
Requires-Dist: pyyaml>=6.0
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Obsidian Knowledge
|
|
2
|
+
|
|
3
|
+
A Claude Code plugin marketplace with skills and hooks for maintaining
|
|
4
|
+
Obsidian knowledge base vaults.
|
|
5
|
+
|
|
6
|
+
## Skills
|
|
7
|
+
|
|
8
|
+
### vault-organizer
|
|
9
|
+
|
|
10
|
+
Maintains vault organization through a single-pass pipeline:
|
|
11
|
+
|
|
12
|
+
- **Sync indexes** — creates and updates `index.md` files with thin pointer entries for managed zones
|
|
13
|
+
- **Organize files** — moves misplaced files to appropriate locations using the Obsidian CLI
|
|
14
|
+
- **Rename ambiguous files** — detects files with non-descriptive names
|
|
15
|
+
(device-generated, hash-based, generic labels), reads their content, and
|
|
16
|
+
renames them following the vault's naming conventions from CLAUDE.md
|
|
17
|
+
- **Fix broken links** — detects unresolved links and resolves them when
|
|
18
|
+
possible, flags ambiguous cases for human review
|
|
19
|
+
- **Report issues** — maintains a `needs-attention.md` worklist for issues
|
|
20
|
+
requiring human judgment
|
|
21
|
+
- **Regenerate reports** — rewrites `reports/open-questions.md` from
|
|
22
|
+
`> [!question]` callouts across `wiki/`, giving agents and humans a
|
|
23
|
+
single place to see unresolved questions flagged in prose
|
|
24
|
+
|
|
25
|
+
### remember-conversations
|
|
26
|
+
|
|
27
|
+
Files valuable conversation outputs as permanent vault notes and updates
|
|
28
|
+
the changelog, so insights compound rather than disappearing into chat
|
|
29
|
+
history:
|
|
30
|
+
|
|
31
|
+
- **Session notes** — two types: `-diary` for narrative accounts (what
|
|
32
|
+
happened, what was tried) and `-convo` for analytical synthesis
|
|
33
|
+
(comparisons, decision rationales, research summaries)
|
|
34
|
+
- **Changelog updates** — creates a terse per-session file in `changelog/`
|
|
35
|
+
summarizing actions taken
|
|
36
|
+
- **Automatic placement** — notes filed in `sessions/` subfolders within
|
|
37
|
+
the relevant subtree, preserving progressive disclosure
|
|
38
|
+
- **Stop hook integration** — a reminder nudges the agent to file
|
|
39
|
+
sessions at the end of each conversation
|
|
40
|
+
|
|
41
|
+
### improve-harness
|
|
42
|
+
|
|
43
|
+
Multi-phase side-quest workflow to fix harness friction. Triggered by
|
|
44
|
+
`/improve-harness <description>` or natural-language frustration phrases.
|
|
45
|
+
The side quest runs as a headless `claude -p --worktree` session that
|
|
46
|
+
produces a proposal (with internal review), receives main-agent
|
|
47
|
+
executive review, then implements (with internal review via
|
|
48
|
+
`subagent-driven-development`) and leaves a branch for human approval.
|
|
49
|
+
|
|
50
|
+
The skill is organized for progressive disclosure: `SKILL.md` is a thin
|
|
51
|
+
index; sub-asset files (`phases.md`, `templates.md`, `conventions.md`)
|
|
52
|
+
hold the details and load only when needed.
|
|
53
|
+
|
|
54
|
+
### deploy-harness
|
|
55
|
+
|
|
56
|
+
Single-purpose skill: merge an approved `improve/<slug>` branch into
|
|
57
|
+
main, bump patch version, push to origin. Called from `improve-harness`
|
|
58
|
+
Phase 5 or invokable manually.
|
|
59
|
+
|
|
60
|
+
## Hooks
|
|
61
|
+
|
|
62
|
+
### Vault protection (PreToolUse)
|
|
63
|
+
|
|
64
|
+
`protect-vault.py` runs before every Bash, Write, and Edit tool call.
|
|
65
|
+
It provides four layers of safety:
|
|
66
|
+
|
|
67
|
+
**Read-only `_sources/` directories.** Folders named `_sources/` anywhere
|
|
68
|
+
in the vault tree are protected from agent writes. These typically hold
|
|
69
|
+
irreplaceable originals (tax records, legal filings, vital docs, property
|
|
70
|
+
deeds). Agents can read them to generate summaries and indexes, but cannot
|
|
71
|
+
create, modify, rename, move, or delete files inside them.
|
|
72
|
+
|
|
73
|
+
**Destructive command guards.** Recursive `rm` and `mv` targeting paths
|
|
74
|
+
that appear to be inside an Obsidian vault are blocked.
|
|
75
|
+
|
|
76
|
+
**Published file guard.** Write and Edit to any vault file with
|
|
77
|
+
`dg-publish: true` in its frontmatter are blocked — edits to published
|
|
78
|
+
files go live on the website and require explicit user confirmation.
|
|
79
|
+
|
|
80
|
+
**Auto-memory redirect.** Agents are blocked from writing operational
|
|
81
|
+
knowledge (`feedback_*.md`, `project_*.md`, `reference_*.md`) to their
|
|
82
|
+
per-project auto-memory. Auto-memory is a silo invisible to other sessions,
|
|
83
|
+
other tools, and vault search. The hook redirects this knowledge to a
|
|
84
|
+
standardized vault location, scoped to the agent's current context:
|
|
85
|
+
|
|
86
|
+
- Inside a git repo → `<vault>/wiki/repos/<owner>/<repo>/memory/` (parsed
|
|
87
|
+
from `git remote get-url origin`; portable across hosts).
|
|
88
|
+
- Outside any repo → `<vault>/wiki/systems/machines/<hostname>/memory/`
|
|
89
|
+
(host-scoped fallback).
|
|
90
|
+
|
|
91
|
+
Each memory dir mirrors Claude's native layout (`MEMORY.md` index plus
|
|
92
|
+
one `feedback_*.md` / `project_*.md` / `reference_*.md` per fact), so
|
|
93
|
+
the workflow is identical — only the storage location changes. The
|
|
94
|
+
SessionStart primer surfaces the resolved path so agents know where
|
|
95
|
+
to read and write at session start. Migrate existing per-project
|
|
96
|
+
memories with `scripts/migrate_claude_memory.py`.
|
|
97
|
+
|
|
98
|
+
**Escape hatch.** Prefix a Bash command with `I_AM_BEING_CAREFUL=1` to
|
|
99
|
+
bypass the `_sources/` and published-file guards after the user explicitly
|
|
100
|
+
confirms. The auto-memory redirect has no escape hatch — write to the wiki
|
|
101
|
+
instead.
|
|
102
|
+
|
|
103
|
+
### For agents: add this line to the user's primary `CLAUDE.md`
|
|
104
|
+
|
|
105
|
+
Built-in Claude auto-memory under `~/.claude/projects/*/memory/` is
|
|
106
|
+
replaced by the `obsidian-knowledge` plugin. Agents should add a single
|
|
107
|
+
pointer to the user's primary memory file (`~/.claude/CLAUDE.md`) so
|
|
108
|
+
sessions on hosts without this plugin still know where to look:
|
|
109
|
+
|
|
110
|
+
```markdown
|
|
111
|
+
Agent memory is managed by the obsidian-knowledge plugin; refer to it
|
|
112
|
+
for memory location, read/write conventions, and session-start recall.
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Stop hooks
|
|
116
|
+
|
|
117
|
+
Stop hooks fire at the end of each Claude Code turn. Each checks
|
|
118
|
+
whether the working directory is inside a configured vault root. They
|
|
119
|
+
have a 5-minute cooldown per session to avoid being noisy in long
|
|
120
|
+
conversations.
|
|
121
|
+
|
|
122
|
+
- **update-changelog.py** — reminds the agent to create a per-session file in
|
|
123
|
+
`changelog/` if the session produced edits, decisions, or discoveries
|
|
124
|
+
- **remind-convos.py** — reminds the agent to preserve session outputs
|
|
125
|
+
(diary notes, convo notes, guides, changelog entries, gotchas)
|
|
126
|
+
- **scan-vault-secrets.py** — runs `detect-secrets` against the vault
|
|
127
|
+
and surfaces unaudited findings to the agent. The plugin makes no
|
|
128
|
+
assumptions about which password manager you use — agents are told
|
|
129
|
+
to follow your vault's documented secrets-management convention, so
|
|
130
|
+
**document yours somewhere agents can find it** (root `CLAUDE.md` or
|
|
131
|
+
a wiki note). The first scan walks the entire vault (slow, ~1 min
|
|
132
|
+
on a few thousand files); subsequent scans are incremental against
|
|
133
|
+
the baseline at `<vault>/.secrets.baseline`.
|
|
134
|
+
|
|
135
|
+
Marks false positives two ways:
|
|
136
|
+
- **Inline sentinel** (recommended for prose notes) — append on the
|
|
137
|
+
same line:
|
|
138
|
+
```
|
|
139
|
+
token = "fake" <!-- pragma: allowlist secret --> # markdown / xml
|
|
140
|
+
token = "fake" # pragma: allowlist secret # yaml / sh / py
|
|
141
|
+
token = "fake" // pragma: allowlist secret # js / go / c
|
|
142
|
+
```
|
|
143
|
+
- **Baseline audit** (batch-mark existing findings):
|
|
144
|
+
```
|
|
145
|
+
detect-secrets audit <vault>/.secrets.baseline
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The hook uses the `detect-secrets` Python API directly with a filter
|
|
149
|
+
set tuned for prose: it drops the `is_likely_id_string` and
|
|
150
|
+
`is_indirect_reference` filters that the `detect-secrets scan` CLI
|
|
151
|
+
applies, because those silently swallow the `token = "..."` pattern
|
|
152
|
+
exactly as it appears in markdown notes. Lower-entropy passphrases
|
|
153
|
+
that elude detect-secrets entirely (dictionary-word passwords in
|
|
154
|
+
narrative prose) can be added one-per-line to
|
|
155
|
+
`<vault>/.secrets.known-leaked` for verbatim string-match alerting.
|
|
156
|
+
|
|
157
|
+
Requires [`uv`](https://docs.astral.sh/uv/) on `PATH` (the hook is a
|
|
158
|
+
uv inline script — `detect-secrets` is installed automatically into a
|
|
159
|
+
uv-managed cache, no global pip install needed).
|
|
160
|
+
|
|
161
|
+
### recall-init (SessionStart)
|
|
162
|
+
|
|
163
|
+
`recall-init.py` runs at every session start. Injects the harness
|
|
164
|
+
primer: a 5-directive context block covering memory location, recall
|
|
165
|
+
via `rg`, capture at session end, friction reflection, and
|
|
166
|
+
user-frustration reflection. The primer stands alone — agents that
|
|
167
|
+
read only this know how to operate within the harness.
|
|
168
|
+
|
|
169
|
+
### reflect-nudge (PostToolUse on Bash)
|
|
170
|
+
|
|
171
|
+
`reflect-nudge.py` fires every 10 bash invocations within a session.
|
|
172
|
+
Continuous — no per-session suppression. Reminds the agent to step back
|
|
173
|
+
and consider whether observed friction warrants a harness improvement.
|
|
174
|
+
|
|
175
|
+
## Commands
|
|
176
|
+
|
|
177
|
+
### /improve-harness <description>
|
|
178
|
+
|
|
179
|
+
Triggers the meta-improvement workflow. The argument is the friction
|
|
180
|
+
description — main agent uses it to seed the incident report and
|
|
181
|
+
generate a slug.
|
|
182
|
+
|
|
183
|
+
### /vault-search <query>
|
|
184
|
+
|
|
185
|
+
Hybrid (BM25 + dense vector) retrieval over the indexed `wiki/` tree.
|
|
186
|
+
Returns ranked `score path` lines. Pass `--all` to override the digest
|
|
187
|
+
filter and include normally-hidden zones (`Inbox/`, `Journal/`).
|
|
188
|
+
|
|
189
|
+
Backed by the [`obsidian-knowledge`](https://pypi.org/project/obsidian-knowledge/)
|
|
190
|
+
package. Vector lane uses [Ollama](https://ollama.com/) with
|
|
191
|
+
[`bge-m3`](https://ollama.com/library/bge-m3) by default (8192-token context,
|
|
192
|
+
multilingual, ~2.3GB). If Ollama is unreachable or the model is not pulled,
|
|
193
|
+
the command silently degrades to FTS-only and prints a single
|
|
194
|
+
`# vector lane off (...)` notice on stderr.
|
|
195
|
+
|
|
196
|
+
## Requirements
|
|
197
|
+
|
|
198
|
+
- [Obsidian](https://obsidian.md/) with CLI enabled
|
|
199
|
+
(`Settings → General → Command line interface`)
|
|
200
|
+
- The following Obsidian settings must be enabled:
|
|
201
|
+
- **Use [[Wikilinks]]** (`Settings → Files and Links`)
|
|
202
|
+
- **Automatically update internal links** (`Settings → Files and Links`)
|
|
203
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) with plugin
|
|
204
|
+
support
|
|
205
|
+
- [`uv`](https://docs.astral.sh/uv/) on `PATH` — required by
|
|
206
|
+
`scan-vault-secrets.py` and the `obsidian-knowledge` CLI
|
|
207
|
+
- [Ollama](https://ollama.com/) installed and running locally, with the
|
|
208
|
+
`bge-m3` embedding model pulled. Required for `/vault-search`'s vector
|
|
209
|
+
lane; optional otherwise (the command will fall back to FTS-only).
|
|
210
|
+
|
|
211
|
+
## Installation
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# 1. Add the marketplace and install the plugin
|
|
215
|
+
claude plugin marketplace add crypdick/obsidian-knowledge
|
|
216
|
+
claude plugin install obsidian-knowledge@obsidian-knowledge
|
|
217
|
+
|
|
218
|
+
# 2. Install Ollama and pull the default embedding model
|
|
219
|
+
# (skip if you don't want vector search)
|
|
220
|
+
brew install ollama # macOS; or see ollama.com/download
|
|
221
|
+
brew services start ollama # macOS; on Linux: `ollama serve` (systemd)
|
|
222
|
+
ollama pull bge-m3
|
|
223
|
+
|
|
224
|
+
# 3. Tell the plugin which vaults to manage
|
|
225
|
+
mkdir -p ~/.config/obsidian-knowledge
|
|
226
|
+
cat > ~/.config/obsidian-knowledge/vaults.yaml <<'EOF'
|
|
227
|
+
vaults:
|
|
228
|
+
- /path/to/your/obsidian/vault
|
|
229
|
+
EOF
|
|
230
|
+
|
|
231
|
+
# 4. Build the initial index (first run takes minutes for a large vault)
|
|
232
|
+
uv run --project ~/.claude/plugins/cache/obsidian-knowledge/obsidian-knowledge \
|
|
233
|
+
obsidian-knowledge reindex --vault /path/to/your/obsidian/vault
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The protection hooks use `vaults.yaml` to know which directories to guard.
|
|
237
|
+
Without it, the `_sources/`, published-file, and destructive-ops rules will
|
|
238
|
+
not fire.
|
|
239
|
+
|
|
240
|
+
### Switching embedding models
|
|
241
|
+
|
|
242
|
+
Override any of the defaults via environment variables:
|
|
243
|
+
|
|
244
|
+
| Variable | Default | Purpose |
|
|
245
|
+
|---|---|---|
|
|
246
|
+
| `MEMWEAVE_EMBEDDING_MODEL` | `ollama/bge-m3` | LiteLLM model identifier |
|
|
247
|
+
| `MEMWEAVE_EMBEDDING_API_BASE` | `http://127.0.0.1:11434` | Ollama / LiteLLM endpoint |
|
|
248
|
+
| `MEMWEAVE_EMBEDDING_API_KEY` | unset | API key (leave unset for Ollama) |
|
|
249
|
+
|
|
250
|
+
When the embedding model changes, the next `/vault-search` call detects the
|
|
251
|
+
mismatch and rebuilds the index automatically. The fingerprint
|
|
252
|
+
(`<model>@<chunk-tokens>/<chunk-overlap>`) is stored alongside the index.
|
|
253
|
+
|
|
254
|
+
### Cache location
|
|
255
|
+
|
|
256
|
+
The embedding DB lives outside the vault, in the per-host XDG cache
|
|
257
|
+
directory:
|
|
258
|
+
|
|
259
|
+
| OS | Path |
|
|
260
|
+
|---|---|
|
|
261
|
+
| Linux | `${XDG_CACHE_HOME:-~/.cache}/obsidian-knowledge/<vault-key>/` |
|
|
262
|
+
| macOS | `~/Library/Caches/obsidian-knowledge/<vault-key>/` |
|
|
263
|
+
|
|
264
|
+
`<vault-key>` is `<vault-dir-name>-<sha256(absolute_path)[:8]>`, so two vaults
|
|
265
|
+
named `obsidian/` on different machines (or in different parents) never
|
|
266
|
+
collide. Each host owns its own embeddings DB — Syncthing and other vault
|
|
267
|
+
sync tools never see it, eliminating cross-device write conflicts.
|
|
268
|
+
|
|
269
|
+
A pre-3.16 install with the old in-vault cache (`<vault>/.config/obsidian-knowledge/cache/`)
|
|
270
|
+
will trigger one auto-rebuild on first use. The old directory is safe to
|
|
271
|
+
delete once the new cache is populated.
|
|
272
|
+
|
|
273
|
+
### Keeping the index fresh
|
|
274
|
+
|
|
275
|
+
There is no built-in file-watcher. Content added or edited between reindexes
|
|
276
|
+
is invisible to `/vault-search` until the next reindex. An hourly cron is
|
|
277
|
+
the recommended baseline:
|
|
278
|
+
|
|
279
|
+
```cron
|
|
280
|
+
# Linux
|
|
281
|
+
0 * * * * $HOME/.local/bin/uv run --project $HOME/src/PERSONAL/obsidian-knowledge obsidian-knowledge reindex --vault $HOME/Documents/obsidian >> $HOME/.cache/obsidian-knowledge/cron.log 2>&1
|
|
282
|
+
|
|
283
|
+
# macOS (Apple Silicon)
|
|
284
|
+
0 * * * * /opt/homebrew/bin/uv run --project $HOME/src/PERSONAL/obsidian-knowledge obsidian-knowledge reindex --vault $HOME/Documents/obsidian >> $HOME/Library/Caches/obsidian-knowledge/cron.log 2>&1
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Incremental reindex is cheap: ~8s wall on a ~1700-file vault with zero
|
|
288
|
+
edits (all files hash-skip). Only modified files get re-embedded. Overlap
|
|
289
|
+
is guarded by an `fcntl.flock` on `<cache>/.reindex.lock` — a second run
|
|
290
|
+
that fires while the first is still active exits cleanly without
|
|
291
|
+
touching the DB.
|
|
292
|
+
|
|
293
|
+
## Usage
|
|
294
|
+
|
|
295
|
+
Invoke the skill directly:
|
|
296
|
+
|
|
297
|
+
> Organize my vault / update indexes / fix broken links / rename ambiguous
|
|
298
|
+
> files / garden the vault
|
|
299
|
+
|
|
300
|
+
Or set up a scheduled run for routine maintenance.
|
|
301
|
+
|
|
302
|
+
The skill stores its state in your vault at
|
|
303
|
+
`Utility/obsidian-knowledge/`:
|
|
304
|
+
|
|
305
|
+
- `changelog/` — per-session terse logs (one file per agent session, 1-liners only)
|
|
306
|
+
- `needs-attention.md` — human-resolved worklist
|
|
307
|
+
- `reports/open-questions.md` — regenerated dashboard of `> [!question]` callouts
|
|
308
|
+
|
|
309
|
+
Historical state was under `.config/obsidian-knowledge/` prior to v1.1.0.
|
|
310
|
+
|
|
311
|
+
### Vault configuration
|
|
312
|
+
|
|
313
|
+
For best results, add a `CLAUDE.md` to your vault root with naming
|
|
314
|
+
conventions and instructions to invoke the skill after structural edits.
|
|
315
|
+
|
|
316
|
+
The vault-organizer respects access zones defined in
|
|
317
|
+
`.claude/vault-zones.yaml`. Create this file to control which folders
|
|
318
|
+
the agent can organize, where indexes are required, and which areas
|
|
319
|
+
are read-only. See the skill's documentation for the expected format.
|
|
320
|
+
|
|
321
|
+
## License
|
|
322
|
+
|
|
323
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Trigger a meta-improvement side quest to fix harness friction. Provide a free-text description of what's wrong.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Improve Harness
|
|
6
|
+
|
|
7
|
+
Trigger the meta-improvement workflow when the harness is causing friction.
|
|
8
|
+
|
|
9
|
+
Read the skill at `${CLAUDE_PLUGIN_ROOT}/skills/improve-harness/SKILL.md` and execute its workflow with the user's friction description as input.
|
|
10
|
+
|
|
11
|
+
User-provided friction description: $ARGUMENTS
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scan the current vault for leaked secrets on demand. Pass `full` to rebuild the baseline from scratch.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Scan Vault Secrets
|
|
6
|
+
|
|
7
|
+
Run the secrets scanner against the vault containing the current working directory. Bypasses the Stop-hook cooldown so it always executes.
|
|
8
|
+
|
|
9
|
+
The scanner is the same one wired up as a Stop hook (`hooks/scan-vault-secrets.py`); this command runs it in `--manual` mode so findings print to stdout instead of being injected as a Stop block.
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Run the scanner. If `$ARGUMENTS` contains the word `full`, append `--full` to delete the baseline first and force a full rescan; otherwise run an incremental scan.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv run "${CLAUDE_PLUGIN_ROOT}/hooks/scan-vault-secrets.py" --manual
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
With `full`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv run "${CLAUDE_PLUGIN_ROOT}/hooks/scan-vault-secrets.py" --manual --full
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
2. Surface the script's stdout verbatim to the user.
|
|
26
|
+
|
|
27
|
+
3. If findings appeared, briefly summarize what should happen next (audit, redact, or allowlist) using the inline guidance the script already prints. Do not start remediating files automatically — the user decides which findings are real.
|
|
28
|
+
|
|
29
|
+
User arguments: $ARGUMENTS
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Hybrid (BM25 + dense vector) search over the Obsidian vault. Returns top-K paths ranked by relevance. Use this before answering non-trivial questions instead of `rg`.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Vault Search
|
|
6
|
+
|
|
7
|
+
Run hybrid retrieval against the vault index. Combines BM25 keyword scoring with dense embedding similarity (Ollama / `bge-m3` by default), fused by memweave. The vector lane gracefully falls back to FTS-only if Ollama is unreachable.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- Looking up a topic, person, system, or concept by meaning, not exact phrase.
|
|
12
|
+
- You want freshness + relevance ranking, not a flat grep dump.
|
|
13
|
+
- Paraphrased queries: ask in your own words, the embed lane handles synonyms.
|
|
14
|
+
|
|
15
|
+
For exact-string lookups (a known function name, a specific token, a literal phrase), `rg` is still faster and exact.
|
|
16
|
+
|
|
17
|
+
## Steps
|
|
18
|
+
|
|
19
|
+
1. Run the search. If `$ARGUMENTS` is empty, ask the user what they want to search for and stop.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
obsidian-knowledge search "$ARGUMENTS"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To include normally-hidden paths (Inbox, Journal, sources), append `--all`:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
obsidian-knowledge search "$ARGUMENTS" --all
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If `obsidian-knowledge` is not found, install it first: `uv tool install obsidian-knowledge`
|
|
32
|
+
|
|
33
|
+
2. Surface the printed `score path` lines verbatim.
|
|
34
|
+
|
|
35
|
+
3. Open the top 1–3 results with `Read` if the user wants the actual content (don't dump everything — paths are cheap, full reads aren't).
|
|
36
|
+
|
|
37
|
+
4. If the first stderr line says `vector lane off`, mention it once so the user knows results are FTS-only and can fix Ollama if they want semantic search back.
|
|
38
|
+
|
|
39
|
+
User arguments: $ARGUMENTS
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# TODO
|
|
2
|
+
|
|
3
|
+
Future work for the obsidian-knowledge plugin. Not bugs — design ideas worth tracking until someone picks them up.
|
|
4
|
+
|
|
5
|
+
## `grade:` YAML frontmatter property
|
|
6
|
+
|
|
7
|
+
Add a `grade:` field to note frontmatter as a self-rated quality marker (e.g., `grade: A`, `grade: B`, `grade: stub`). Used to:
|
|
8
|
+
|
|
9
|
+
- Power the `wiki/QUALITY.md` scorecard (currently a stub idea — see vault-organizer SKILL.md history) by aggregating grades per folder
|
|
10
|
+
- Let the SessionStart `doctor.py` digest surface low-graded or ungraded notes alongside convention violations
|
|
11
|
+
- Drive a future `vault-organizer --grade` mode that prompts for grade on any note missing one
|
|
12
|
+
|
|
13
|
+
**Open questions:** grading scale (letter? 1–5? stub/draft/solid/canonical?); whether to require grades on all wiki notes or only on indexes; whether the grade is human-only or an agent can suggest one based on length, link density, and last-edited date.
|
|
14
|
+
|
|
15
|
+
## Note-improver agent
|
|
16
|
+
|
|
17
|
+
A subagent that takes a single wiki note as input and proposes improvements: tighter prose, broken-link triage, missing wikilink suggestions (find related notes that *should* be linked), frontmatter hygiene, grade suggestion (see above). Should be read-only by default, emitting a diff for human review rather than auto-editing.
|
|
18
|
+
|
|
19
|
+
**Trigger ideas:** invoked manually via `/improve-note <path>`; suggested by `doctor.py` for low-graded notes; chained from `vault-organizer` when it encounters a stub link target that resolves to a real-but-thin note.
|
|
20
|
+
|
|
21
|
+
**Constraints:** never edits primary file content without confirmation (matches vault-organizer's discipline). Should respect `dg-publish: true` (publish-guard already blocks edits to those).
|
|
22
|
+
|
|
23
|
+
## Convention-sweep code-block awareness — done
|
|
24
|
+
|
|
25
|
+
Wikilink-extension check now skips fenced (`` ``` `` / `~~~`) blocks and inline code spans. Logged here only for the next item ↓
|
|
26
|
+
|
|
27
|
+
## Convention-sweep: skip more false-positive sources
|
|
28
|
+
|
|
29
|
+
- Skip wikilinks inside HTML comments (`<!-- ... -->`)
|
|
30
|
+
- Skip dated-folder check for files explicitly tagged `type: template` in frontmatter
|
|
31
|
+
- Treat YAML errors in `_drafts/` and similar staging zones as warnings, not violations
|