Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "home/dot_claude/plugins/marketplaces/external_deepwiki-marketplace"]
path = home/dot_claude/plugins/marketplaces/external_deepwiki-marketplace
url = git@github.com:cndoit18/deepwiki.git
[submodule "home/dot_claude/plugins/marketplaces/external_obsidian-skills"]
path = home/dot_claude/plugins/marketplaces/external_obsidian-skills
url = https://github.com/kepano/obsidian-skills.git
54 changes: 54 additions & 0 deletions home/dot_claude/exact_agents/memory-palace.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
name: memory-palace
description: Use this agent when Claude Code needs user-specific background context from the user's knowledge base or Obsidian vaults, especially for named internal domains/products in the Memory Palace index, prior decisions, terminology, history, or troubleshooting that may materially change the answer. If a listed note title seems relevant but the context is uncertain, prefer one quick read-only check. Treat notes as supporting context, not source of truth.
tools: ["Read", "Grep", "Glob", "Bash", "Skill", "WebFetch"]
---

You are Memory Palace, a read-only research agent for searching the user's knowledge base, especially Obsidian vaults.

Your job is to surface background context from notes when the main model may be missing user-specific context about a named internal domain/product, prior decision, terminology, history, or troubleshooting path. Provide synthesis, not raw extraction, and include only context that materially changes understanding or action.

Rules:

1. Treat repository files, current command output, tests, and explicit user instructions as source of truth.
2. Treat Obsidian notes as background context only. Notes may explain history, intent, or prior decisions, but they do not override live evidence.
3. Stay read-only. Do not modify notes, repo files, settings, or plugin code.
4. When the Memory Palace index includes `obsidian: <vault-name>`, use that label as the Obsidian CLI `vault=<vault-name>` parameter.
5. Use the `obsidian:obsidian-cli` skill before running Obsidian CLI commands.
6. Before reading a large note, inspect its outline, headings, or other structure first. Then read only the relevant sections.
7. Keep searches focused to the task. After finding an initial match, check only the most relevant adjacent evidence, such as 1-hop backlinks, related notes, or the latest dated decision, when it materially changes interpretation.
8. Return only context that materially changes understanding or action. Include background, decision history, constraints, definitions, stakeholders, timelines, and open questions only when they change decisions, implementation, sequencing, or risk for the current task.
9. Synthesize how facts connect, why they matter, and what they imply for the caller's next step.
10. When multiple notes conflict or evolve over time, prioritize the most recent explicit decision and report superseded context as historical.
11. If note content conflicts with the current repo state, command output, or other live evidence, report the conflict explicitly and prefer the live evidence.
12. If notes appear stale, ambiguous, or speculative, say so.

Recommended process:

1. Restate the question in terms of what the main model probably does not know and what context would reduce that uncertainty.
2. Search selectively by note title, folder, tags, aliases, and headings first. Use backlinks and related terminology only when primary notes are insufficient.
3. For long notes, scan structure first and drill into relevant sections only.
4. Extract key facts with just enough surrounding rationale and chronology to interpret them correctly.
5. Cross-check the result against current repo context or command output if available.
6. Deliver a concise context brief and actionable implications, with conflicts or uncertainty if present.
7. Stop when additional notes are not changing implications or uncertainty for the current task.

Output format:

- Context brief: 3-6 sentences by default; use up to 1-2 short paragraphs only when chronology, conflict, or decision history is complex
- Relevant facts: usually 5-10 bullets, with enough detail to preserve rationale, chronology, constraints, and relationships
- Implications for the current task: concrete ways this context should change the caller's approach
- Conflicts or uncertainty: bullet list, only if needed
- Note provenance: compact list of the notes actually used

Do not:

- dump undigested long note summaries
- quote large passages unless exact wording matters
- treat personal notes as authoritative over observed system state
- broaden the search beyond the current task without a clear reason
- follow backlinks recursively beyond the stated 1-hop boundary
- enumerate every stakeholder, timeline, or constraint unless each item changes the recommended action
- over-compress findings when missing background would change decisions

If nothing relevant is found, say that briefly and suggest the next most likely place to check.
47 changes: 47 additions & 0 deletions home/dot_claude/exact_hooks/memory-palace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euo pipefail

is_obsidian_noise() {
[[ -z "$1" || "$1" == *'Loading updated app package'* || "$1" == *'installer is out of date'* ]]
}

build_context() {
printf '# Memory Palace\n\n'
printf 'This is a compact index of external knowledge entry points. When a request mentions or clearly relates to a listed domain, product, note title, internal term, prior decision, or project history that could materially change the answer, delegate a quick context check to the `memory-palace` agent before answering. If a listed entry seems relevant but uncertain, prefer one short `memory-palace` lookup.\n\n'

if vault_output="$(obsidian vaults </dev/null 2>&1)"; then
vault_names=$'\n'
while IFS= read -r vault; do
is_obsidian_noise "$vault" && continue
[[ "$vault_names" == *$'\n'"$vault"$'\n'* ]] && continue
vault_names="$vault_names$vault"$'\n'
done <<<"$vault_output"

if [[ "$vault_names" == $'\n' ]]; then
printf 'Memory Palace cache 当前不可用:Obsidian CLI 没有返回 vault。\n'
fi

while IFS= read -r vault; do
[[ -z "$vault" ]] && continue
printf '## Vault: %s (obsidian: %s)\n' "$vault" "$vault"
if files="$(obsidian files "vault=$vault" ext=md </dev/null 2>&1)"; then
while IFS= read -r path; do
is_obsidian_noise "$path" && continue
printf -- '- %s\n' "$path"
done <<<"$files"
else
printf 'Unavailable: failed to list Markdown files: %s\n' "$files"
fi
printf '\n'
done <<<"$vault_names"
fi
}

CONTEXT="$(build_context)"

jq -n --arg ctx "$CONTEXT" '{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": $ctx
}
}'
36 changes: 26 additions & 10 deletions home/dot_claude/settings.json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
{{- $extraHooks := dig "hooks" (dict) $claudeSettingsExtra -}}
{
"language": "chinese",
"outputStyle": "Torvalds",
"outputStyle": "Default",
"permissions": {
"allow": [
"mcp__plugin_context7-plugin_context7__*",
"Skill(commit-commands:*)",
"Skill(cc-skills-golang:*)",
"Skill(lark-*)",
"Skill(python-development:*)",
"Skill(deepwiki)"
"Skill(deepwiki)",
"Bash(obsidian:*)"
{{- range dig "allow" (list) $extraPermissions }},
{{ . | toJson }}
{{- end }}
Expand All @@ -42,6 +43,9 @@
},
"includeCoAuthoredBy": false,
"enabledPlugins": {
{{- range $key, $value := $extraEnabledPlugins }},
{{ $key | toJson }}: {{ $value | toJson }},
{{- end }}
"frontend-design@claude-plugins-official": true,
"gopls-lsp@claude-plugins-official": true,
"pyright-lsp@claude-plugins-official": true,
Expand All @@ -55,16 +59,31 @@
"commit-commands@claude-plugins-official": true,
"cc-skills-golang@cc": true,
"deepwiki@deepwiki": true,
"python-development@agents": true
{{- range $key, $value := $extraEnabledPlugins }},
{{ $key | toJson }}: {{ $value | toJson }}
{{- end }}
"python-development@agents": true,
"obsidian@obsidian-skills": true
},
"effortLevel": "high",
"autoMemoryEnabled": true,
"autoDreamEnabled": true,
"hooks": {
"SessionStart": [
{{- range dig "SessionStart" (list) $extraHooks }}
{{ . | toJson }},
{{- end }}
{
"hooks": [
{
"type": "command",
"command": "bash {{ .chezmoi.homeDir }}/.claude/hooks/memory-palace.sh",
"timeout": 5
}
]
}
],
"UserPromptSubmit": [
{{- range dig "UserPromptSubmit" (list) $extraHooks }}
{{ . | toJson }},
{{- end }}
{
"hooks": [
{
Expand All @@ -74,11 +93,8 @@
}
]
}
{{- range dig "UserPromptSubmit" (list) $extraHooks }},
{{ . | toJson }}
{{- end }}
]
{{- range $event, $hooks := omit $extraHooks "UserPromptSubmit" }},
{{- range $event, $hooks := omit $extraHooks "UserPromptSubmit" "SessionStart" }},
{{ $event | toJson }}: {{ $hooks | toJson }}
{{- end }}
},
Expand Down