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.
Files changed (98) hide show
  1. obsidian_knowledge-3.19.0/.claude/hookify.require-plugin-version-bump.md +25 -0
  2. obsidian_knowledge-3.19.0/.claude-plugin/marketplace.json +17 -0
  3. obsidian_knowledge-3.19.0/.claude-plugin/plugin.json +79 -0
  4. obsidian_knowledge-3.19.0/.github/workflows/publish.yml +24 -0
  5. obsidian_knowledge-3.19.0/.gitignore +7 -0
  6. obsidian_knowledge-3.19.0/LICENSE +22 -0
  7. obsidian_knowledge-3.19.0/PKG-INFO +10 -0
  8. obsidian_knowledge-3.19.0/README.md +323 -0
  9. obsidian_knowledge-3.19.0/commands/improve-harness.md +11 -0
  10. obsidian_knowledge-3.19.0/commands/scan-secrets.md +29 -0
  11. obsidian_knowledge-3.19.0/commands/vault-search.md +39 -0
  12. obsidian_knowledge-3.19.0/docs/TODO.md +31 -0
  13. obsidian_knowledge-3.19.0/docs/superpowers/plans/2026-04-25-improve-harness-implementation.md +1608 -0
  14. obsidian_knowledge-3.19.0/docs/superpowers/plans/2026-05-12-changelog-reform.md +804 -0
  15. obsidian_knowledge-3.19.0/docs/superpowers/specs/2026-04-25-improve-harness-design.md +331 -0
  16. obsidian_knowledge-3.19.0/docs/superpowers/specs/2026-05-12-changelog-reform-design.md +103 -0
  17. obsidian_knowledge-3.19.0/hermes_plugin/__init__.py +302 -0
  18. obsidian_knowledge-3.19.0/hermes_plugin/plugin.yaml +8 -0
  19. obsidian_knowledge-3.19.0/hooks/doctor.py +175 -0
  20. obsidian_knowledge-3.19.0/hooks/enforce-conventions.py +120 -0
  21. obsidian_knowledge-3.19.0/hooks/hookslib/__init__.py +1 -0
  22. obsidian_knowledge-3.19.0/hooks/hookslib/patterns.py +131 -0
  23. obsidian_knowledge-3.19.0/hooks/hookslib/recall_init_lib.py +34 -0
  24. obsidian_knowledge-3.19.0/hooks/hookslib/reflect_counter.py +35 -0
  25. obsidian_knowledge-3.19.0/hooks/hookslib/repo_memory.py +139 -0
  26. obsidian_knowledge-3.19.0/hooks/hookslib/stop_hook.py +50 -0
  27. obsidian_knowledge-3.19.0/hooks/hookslib/transcript.py +38 -0
  28. obsidian_knowledge-3.19.0/hooks/hookslib/vault_config.py +49 -0
  29. obsidian_knowledge-3.19.0/hooks/hookslib/vault_policy.py +57 -0
  30. obsidian_knowledge-3.19.0/hooks/nudge-index-sync.py +97 -0
  31. obsidian_knowledge-3.19.0/hooks/protect-vault.py +650 -0
  32. obsidian_knowledge-3.19.0/hooks/recall-init.py +73 -0
  33. obsidian_knowledge-3.19.0/hooks/reflect-nudge.py +54 -0
  34. obsidian_knowledge-3.19.0/hooks/remind-convos.py +55 -0
  35. obsidian_knowledge-3.19.0/hooks/remind-convos.sh +6 -0
  36. obsidian_knowledge-3.19.0/hooks/scan-vault-secrets.py +484 -0
  37. obsidian_knowledge-3.19.0/hooks/update-changelog.py +42 -0
  38. obsidian_knowledge-3.19.0/hooks/update-changelog.sh +6 -0
  39. obsidian_knowledge-3.19.0/lib/__init__.py +0 -0
  40. obsidian_knowledge-3.19.0/lib/vault_index/__init__.py +19 -0
  41. obsidian_knowledge-3.19.0/lib/vault_index/cli.py +217 -0
  42. obsidian_knowledge-3.19.0/lib/vault_index/config.py +44 -0
  43. obsidian_knowledge-3.19.0/lib/vault_index/filters.py +86 -0
  44. obsidian_knowledge-3.19.0/lib/vault_index/indexer.py +398 -0
  45. obsidian_knowledge-3.19.0/lib/vault_index/primer.py +58 -0
  46. obsidian_knowledge-3.19.0/pyproject.toml +27 -0
  47. obsidian_knowledge-3.19.0/scripts/build_memory_indexes.py +87 -0
  48. obsidian_knowledge-3.19.0/scripts/local_smoke_test.py +89 -0
  49. obsidian_knowledge-3.19.0/scripts/migrate_changelog.py +134 -0
  50. obsidian_knowledge-3.19.0/scripts/migrate_claude_memory.py +226 -0
  51. obsidian_knowledge-3.19.0/skills/deploy-harness/SKILL.md +70 -0
  52. obsidian_knowledge-3.19.0/skills/improve-harness/SKILL.md +69 -0
  53. obsidian_knowledge-3.19.0/skills/improve-harness/conventions.md +38 -0
  54. obsidian_knowledge-3.19.0/skills/improve-harness/phases.md +122 -0
  55. obsidian_knowledge-3.19.0/skills/improve-harness/templates.md +45 -0
  56. obsidian_knowledge-3.19.0/skills/obsidian-knowledge/SKILL.md +105 -0
  57. obsidian_knowledge-3.19.0/skills/remember-conversations/SKILL.md +191 -0
  58. obsidian_knowledge-3.19.0/skills/vault-organizer/SKILL.md +116 -0
  59. obsidian_knowledge-3.19.0/skills/vault-organizer/convention-sweep.py +122 -0
  60. obsidian_knowledge-3.19.0/skills/vault-organizer/filter-unresolved-links.py +113 -0
  61. obsidian_knowledge-3.19.0/skills/vault-organizer/find-open-questions.py +106 -0
  62. obsidian_knowledge-3.19.0/skills/vault-organizer/fix-stacked-frontmatter.py +156 -0
  63. obsidian_knowledge-3.19.0/skills/vault-organizer/lib/broken-links.md +48 -0
  64. obsidian_knowledge-3.19.0/skills/vault-organizer/lib/index-format.md +54 -0
  65. obsidian_knowledge-3.19.0/skills/vault-organizer/lib/note-types.md +38 -0
  66. obsidian_knowledge-3.19.0/skills/vault-organizer/lib/rename-files.md +33 -0
  67. obsidian_knowledge-3.19.0/skills/vault-organizer/lib/stacked-frontmatter.md +77 -0
  68. obsidian_knowledge-3.19.0/skills/vault-organizer/lib/state-files.md +43 -0
  69. obsidian_knowledge-3.19.0/skills/vault-organizer/vault-audit.py +248 -0
  70. obsidian_knowledge-3.19.0/tests/__init__.py +0 -0
  71. obsidian_knowledge-3.19.0/tests/conftest.py +83 -0
  72. obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/.claude/obsidian-knowledge.yaml +12 -0
  73. obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/Inbox/random.md +2 -0
  74. obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/Journal/diary.md +2 -0
  75. obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/wiki/python.md +2 -0
  76. obsidian_knowledge-3.19.0/tests/fixtures/sample_vault/wiki/rust.md +2 -0
  77. obsidian_knowledge-3.19.0/tests/fixtures/transcript_new_file_no_index.jsonl +1 -0
  78. obsidian_knowledge-3.19.0/tests/fixtures/transcript_new_file_with_index.jsonl +2 -0
  79. obsidian_knowledge-3.19.0/tests/test_cli.py +117 -0
  80. obsidian_knowledge-3.19.0/tests/test_config.py +67 -0
  81. obsidian_knowledge-3.19.0/tests/test_doctor.py +81 -0
  82. obsidian_knowledge-3.19.0/tests/test_enforce_conventions.py +151 -0
  83. obsidian_knowledge-3.19.0/tests/test_filters.py +129 -0
  84. obsidian_knowledge-3.19.0/tests/test_hermes_provider.py +176 -0
  85. obsidian_knowledge-3.19.0/tests/test_indexer.py +213 -0
  86. obsidian_knowledge-3.19.0/tests/test_migrate_changelog.py +209 -0
  87. obsidian_knowledge-3.19.0/tests/test_nudge_index_sync.py +68 -0
  88. obsidian_knowledge-3.19.0/tests/test_patterns.py +163 -0
  89. obsidian_knowledge-3.19.0/tests/test_primer.py +19 -0
  90. obsidian_knowledge-3.19.0/tests/test_protect_vault_memory_redirect.py +108 -0
  91. obsidian_knowledge-3.19.0/tests/test_recall_init.py +70 -0
  92. obsidian_knowledge-3.19.0/tests/test_recall_init_lib.py +28 -0
  93. obsidian_knowledge-3.19.0/tests/test_reflect_counter.py +33 -0
  94. obsidian_knowledge-3.19.0/tests/test_reflect_nudge.py +72 -0
  95. obsidian_knowledge-3.19.0/tests/test_repo_memory.py +106 -0
  96. obsidian_knowledge-3.19.0/tests/test_scan_vault_secrets.py +137 -0
  97. obsidian_knowledge-3.19.0/tests/test_transcript.py +44 -0
  98. 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,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .DS_Store
4
+ .worktrees/
5
+ .improve-harness/
6
+ # Generated index cache (created by reindex CLI and indexer tests)
7
+ tests/fixtures/sample_vault/.config/
@@ -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